DEV Community

Cover image for Getting started with GraphQL in .NET 6 - Part 2 (Query + Mutation to Database)
Bervianto Leo Pratama
Bervianto Leo Pratama

Posted on

Getting started with GraphQL in .NET 6 - Part 2 (Query + Mutation to Database)

Welcome to our second part to learn more about GraphQL! I'm so excited about GraphQL. Since, I just learn this maybe about last 1-3 months. I hope you can give me some advises or some suggestions about my articles. Let's go, we learn more the GraphQL.

Prepare your tools

  1. Since .NET 6 finally released and VS 2022 released too. I use VS 2022 to help me more about Database. But, don't worry, if you use Visual Studio Code, you still can follow step by step, I will bring you some extra steps.

  2. Install SQL Server. From here - if you more familiar with Docker, I suggest you to use the docker, they support in the Linux, check here. That is why I suggest you to use Docker instead, for Linux user. Note: If you want to try another databases, feel free to choose your favorite database. You will need to update some code, like dependencies and when settings the DbContext.

Install Dependencies

Your final code (GraphQLNetExample.csproj) will be like this:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="GraphQL" Version="4.6.1" />
    <PackageReference Include="GraphQL.MicrosoftDI" Version="4.6.1" />
    <PackageReference Include="GraphQL.Server.Authorization.AspNetCore" Version="5.0.2" />
    <PackageReference Include="GraphQL.Server.Transports.AspNetCore.SystemTextJson" Version="5.0.2" />
    <PackageReference Include="GraphQL.Server.Ui.Altair" Version="5.0.2" />
    <PackageReference Include="GraphQL.SystemTextJson" Version="4.6.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.0">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.0">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
  </ItemGroup>

</Project>
Enter fullscreen mode Exit fullscreen mode

We are installing some dependencies about EntityFrameworkCore. The manual step is like this (if you use dotnet cli):

  1. dotnet add GraphQLNetExample package Microsoft.EntityFrameworkCore.Design
  2. dotnet add GraphQLNetExample package Microsoft.EntityFrameworkCore.SqlServer - feel free to change with your favorite database.
  3. dotnet add GraphQLNetExample package Microsoft.EntityFrameworkCore.Design

Prepare our databases

  • Create DbContext. My side, write at EntityFramework/NotesContext.cs.
using GraphQLNetExample.Notes;
using Microsoft.EntityFrameworkCore;

namespace GraphQLNetExample.EntityFramework
{
    public class NotesContext : DbContext
    {
        public DbSet<Note> Notes { get; set; }

        public NotesContext(DbContextOptions options) : base(options)
        {

        }
    }
}
Enter fullscreen mode Exit fullscreen mode
  • Update Notes/Note.cs, in this case, I add Required annotation.
using System.ComponentModel.DataAnnotations;

namespace GraphQLNetExample.Notes;

public class Note
{
    public Guid Id { get; set; }
    [Required]
    public string Message { get; set; }
}
Enter fullscreen mode Exit fullscreen mode
  • Update Program.cs, we register the DbContext. Again, feel free to setup with your favorite database.
// ... another existing code

// Add services to the container.
builder.Services.AddDbContext<NotesContext>(options =>
{
    options.UseSqlServer(builder.Configuration.GetConnectionString("Default"));
});
builder.Services.AddSingleton<ISchema, NotesSchema>(services => new NotesSchema(new SelfActivatingServiceProvider(services)));

// ... another existing code
Enter fullscreen mode Exit fullscreen mode
  • Update appsettings.json, to add the Connection String. Please update the database, User, and Password section with your server configuration.
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "Default": "Server=localhost;Database=graphqltutorial;User Id=sa;Password=;"
  }
}
Enter fullscreen mode Exit fullscreen mode
  • Don't forget to create your database in SQL Server.

  • Add Migration. Because I use Visual Studio 2022, so I can use Add-Migration BaseNoteModel, run this command at Package Manager Console. How to navigate? Tools > NuGet Package Manager > Package Manager Console.

Add Migration

Note: If you use dotnet ef & dotnet cli, please refer to this. In that post, I provide you some steps to use the dotnet cli & dotnet ef with dotnet tools.

  • Update database. When use Visual Studio, run this: Updata-Database, to make our database sync with the current migration.

Update Database

  • Yey, your database is ready!

Update Query & Add a Mutation

  • Create a Mutation file, Notes/NotesMutation.cs. We use string type because we only have 1 field only, but if we have larger columns, I suggest to write our input type.
using GraphQL;
using GraphQL.Types;
using GraphQLNetExample.EntityFramework;

namespace GraphQLNetExample.Notes
{
    public class NotesMutation : ObjectGraphType
    {
        public NotesMutation()
        {
            Field<NoteType>(
                "createNote",
                arguments: new QueryArguments(
                    new QueryArgument<NonNullGraphType<StringGraphType>> { Name = "message"}
                ),
                resolve: context =>
                {
                    var message = context.GetArgument<string>("message");
                    var notesContext = context.RequestServices.GetRequiredService<NotesContext>();
                    var note = new Note
                    {
                        Message = message,
                    };
                    notesContext.Notes.Add(note);
                    notesContext.SaveChanges();
                    return note;
                }
            );
        }
    }
}
Enter fullscreen mode Exit fullscreen mode
  • Update our query: Notes/NotesQuery.cs. Our final query will looks like this:
using GraphQL.Types;
using GraphQLNetExample.EntityFramework;

namespace GraphQLNetExample.Notes;

public class NotesQuery : ObjectGraphType
{
    public NotesQuery()
    {
        Field<ListGraphType<NoteType>>("notes", resolve: context => new List<Note> {
          new Note { Id = Guid.NewGuid(), Message = "Hello World!" },
          new Note { Id = Guid.NewGuid(), Message = "Hello World! How are you?" }
        });
        Field<ListGraphType<NoteType>>("notesFromEF", resolve: context =>
        {
            var notesContext = context.RequestServices.GetRequiredService<NotesContext>();
            return notesContext.Notes.ToList();
        }
        );
    }
}
Enter fullscreen mode Exit fullscreen mode
  • Register our Mutation to Schema. Update Notes/NotesSchema.cs.
using GraphQL.Types;

namespace GraphQLNetExample.Notes;

public class NotesSchema : Schema
{
    public NotesSchema(IServiceProvider serviceProvider) : base(serviceProvider)
    {
        Query = serviceProvider.GetRequiredService<NotesQuery>();
        Mutation = serviceProvider.GetRequiredService<NotesMutation>();
    }
}
Enter fullscreen mode Exit fullscreen mode
  • Yes, your GraphQL is ready!

Test our GraphQL

  • I will test from mutation part first.
mutation
{
  createNote(message: "Hello World!")
  {
      id
      message
  }
}
Enter fullscreen mode Exit fullscreen mode

Test Mutation

  • Now, we try to test our query. I add original (in memory), to check the different.
{
  notesFromEF {
    id
    message
  }
  notes {
    id
    message
  }
}
Enter fullscreen mode Exit fullscreen mode

Test Query

Thank you

For the repository, you can visit here:

GraphQL .NET Example

GraphQL example implementation in .NET 6.

LICENSE

MIT

I suggest you to learn more about data access layer. You can learn from here. So, hopefully you don't touch DbContext directly. I touch DbContext directly because this is still simple application and small project, if the project more larger, you will need the data access layer.

I'm not sure yet for the third part. Yes, we will have other parts, but not sure yet. Either I will add Authentication/Authorization parts, or just move to how we call the GraphQL in FrontEnd side, I will use the React.js for this. If you have a suggestion, feel free to comment here.

Finally, thank you for your attention and read until this section. Have great days!

Thank you

Discussion (0)