Introduction to GraphQL on the .NET Platform
GraphQL is a query language for APIs that allows clients to request only the data they actually need. Unlike REST, where the response structure is strictly defined by the server, GraphQL enables flexible query formation. In this tutorial, we will build a full-fledged GraphQL API in C# using the Hot Chocolate framework — the most popular solution for .NET.
We will go from setup to creating complex queries with mutations and subscriptions. This article is intended for developers familiar with the basics of C# and ASP.NET Core.
1. Project Setup and Dependency Installation
First, let's create a new ASP.NET Core project. You can use Visual Studio, Rider, or the command line.
dotnet new web -n GraphQLDemocd GraphQLDemoNow, install the Hot Chocolate package — the main tool for working with GraphQL in .NET:
dotnet add package HotChocolate.AspNetCoreAdditionally, to work with queries via the GraphQL IDE (Banana Cake Pop), install:
dotnet add package HotChocolate.AspNetCore.Playground1.1 Basic Configuration of Program.cs
Open the Program.cs file and configure the services:
var builder = WebApplication.CreateBuilder(args);
builder.Services .AddGraphQLServer() .AddQueryType<Query>();
var app = builder.Build();
app.MapGraphQL();
app.Run();Note: we register Query — this is our root type for reading data. It is empty for now, but we will populate it.
2. Creating the Data Model and First Query
GraphQL works with types. Let's create a simple Book model:
public class Book{ public int Id { get; set; } public string Title { get; set; } public string Author { get; set; } public int Year { get; set; }}Now, define the Query class that will return data:
public class Query{ private static List<Book> _books = new() { new Book { Id = 1, Title = "1984", Author = "George Orwell", Year = 1949 }, new Book { Id = 2, Title = "Clean Code", Author = "Robert C. Martin", Year = 2008 } };
public IQueryable<Book> GetBooks() => _books.AsQueryable();
public Book? GetBookById(int id) => _books.FirstOrDefault(b => b.Id == id);}Run the application and open http://localhost:5000/graphql. You will see Banana Cake Pop — the built-in IDE for testing queries. Try executing:
{ books { title author }}You will receive only the fields you requested — this is the power of GraphQL.
3. Mutations for Data Modification
Mutations are the equivalent of POST/PUT/DELETE in REST. They allow you to modify data on the server. Let's add the ability to add new books.
3.1 Defining the Input Type
Create a class for the mutation input data:
public class AddBookInput{ public string Title { get; set; } public string Author { get; set; } public int Year { get; set; }}3.2 Implementing the Mutation
Add the Mutation class:
public class Mutation{ private static List<Book> _books = new() { new Book { Id = 1, Title = "1984", Author = "George Orwell", Year = 1949 }, new Book { Id = 2, Title = "Clean Code", Author = "Robert C. Martin", Year = 2008 } };
public Book AddBook(AddBookInput input) { var newBook = new Book { Id = _books.Max(b => b.Id) + 1, Title = input.Title, Author = input.Author, Year = input.Year }; _books.Add(newBook); return newBook; }