GraphQL API с C#: пошаговый туториал для .NET разработчиков

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение в GraphQL на платформе .NET

GraphQL — это язык запросов для API, который предоставляет клиентам возможность получать только те данные, которые им действительно нужны. В отличие от REST, где структура ответа жестко определена сервером, GraphQL позволяет гибко формировать запросы. В этом туториале мы создадим полноценный GraphQL API на C# с использованием фреймворка Hot Chocolate — самого популярного решения для .NET.

Мы пройдем путь от установки до создания сложных запросов с мутациями и подписками. Статья рассчитана на разработчиков, знакомых с основами C# и ASP.NET Core.

1. Настройка проекта и установка зависимостей

Для начала создадим новый проект ASP.NET Core. Вы можете использовать Visual Studio, Rider или командную строку.

dotnet new web -n GraphQLDemo
cd GraphQLDemo

Теперь установим пакет Hot Chocolate — основной инструмент для работы с GraphQL в .NET:

dotnet add package HotChocolate.AspNetCore

Дополнительно для работы с запросами через GraphQL IDE (Banana Cake Pop) установим:

dotnet add package HotChocolate.AspNetCore.Playground

1.1 Базовая конфигурация Program.cs

Откройте файл Program.cs и настройте сервисы:

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddGraphQLServer()
    .AddQueryType<Query>();

var app = builder.Build();

app.MapGraphQL();

app.Run();

Обратите внимание: мы регистрируем Query — это наш корневой тип для чтения данных. Пока он пуст, но мы его наполним.

2. Создание модели данных и первого запроса

GraphQL работает с типами. Создадим простую модель Book:

public class Book
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Author { get; set; }
    public int Year { get; set; }
}

Теперь определим класс Query, который будет возвращать данные:

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);
}

Запустите приложение и откройте http://localhost:5000/graphql. Вы увидите Banana Cake Pop — встроенную IDE для тестирования запросов. Попробуйте выполнить:

{
  books {
    title
    author
  }
}

Вы получите только те поля, которые запросили — в этом сила GraphQL.

3. Мутации для изменения данных

Мутации — это аналог POST/PUT/DELETE в REST. Они позволяют изменять данные на сервере. Добавим возможность добавлять новые книги.

3.1 Определение входного типа

Создадим класс для входных данных мутации:

public class AddBookInput
{
    public string Title { get; set; }
    public string Author { get; set; }
    public int Year { get; set; }
}

3.2 Реализация мутации

Добавим класс Mutation:

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;
    }
}

Не забудьте зарегистрировать мутацию в Program.cs:

builder.Services
    .AddGraphQLServer()
    .AddQueryType<Query>()
    .AddMutationType<Mutation>();

Теперь можно выполнить мутацию через Banana Cake Pop:

mutation {
  addBook(input: { title: "Dune", author: "Frank Herbert", year: 1965 }) {
    id
    title
  }
}

4. Подписки (Subscriptions) для real-time уведомлений

Подписки позволяют клиентам получать уведомления в реальном времени при изменениях данных. Это полезно для чатов, уведомлений или ленты новостей.

4.1 Настройка WebSocket

Установите дополнительный пакет:

dotnet add package HotChocolate.AspNetCore.Subscriptions

Добавьте поддержку WebSocket в Program.cs:

builder.Services
    .AddGraphQLServer()
    .AddQueryType<Query>()
    .AddMutationType<Mutation>()
    .AddSubscriptionType<Subscription>();

app.UseWebSockets();

4.2 Реализация подписки

Создадим класс Subscription:

public class Subscription
{
    [Subscribe]
    public Book OnBookAdded([EventMessage] Book book) => book;
}

Теперь нужно изменить мутацию, чтобы она публиковала событие при добавлении книги. Используем интерфейс ITopicEventSender:

public class Mutation
{
    public async Task<Book> AddBookAsync(AddBookInput input, [Service] ITopicEventSender eventSender)
    {
        var newBook = new Book { ... };
        await eventSender.SendAsync(nameof(Subscription.OnBookAdded), newBook);
        return newBook;
    }
}

Теперь клиенты могут подписаться на добавление книг:

subscription {
  onBookAdded {
    id
    title
    author
  }
}

5. Фильтрация, сортировка и пагинация

Hot Chocolate поддерживает встроенные возможности для фильтрации и сортировки. Установите пакет:

dotnet add package HotChocolate.Data

Обновите метод получения книг в Query:

public class Query
{
    [UseFiltering]
    [UseSorting]
    public IQueryable                

Блоги

Рекомендаций по книгам