GraphQL API с C#: Пошаговый туториал на практике

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

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

Начать курс

Введение: Почему GraphQL и C# — идеальная пара

Современная веб-разработка требует гибких и производительных API. REST API, несмотря на свою популярность, часто страдает от over-fetching (получение лишних данных) и under-fetching (необходимость нескольких запросов для получения полной информации). GraphQL решает эти проблемы, позволяя клиенту запрашивать только то, что ему нужно, за один запрос.

В этом туториале мы создадим полноценный GraphQL API на C# с использованием библиотеки Hot Chocolate — самой популярной реализации GraphQL для .NET. Вы узнаете, как настроить сервер, определить схему, реализовать запросы (queries), мутации (mutations) и подписки (subscriptions). Все примеры кода будут практическими и готовыми к использованию.

Для кого этот материал: для .NET-разработчиков, которые хотят освоить GraphQL, и для тех, кто ищет альтернативу REST. Базовые знания C# и ASP.NET Core будут полезны, но не обязательны.

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

Создание проекта ASP.NET Core

Начнем с создания нового проекта. Откройте терминал или командную строку и выполните:

dotnet new web -n GraphQLDemo
cd GraphQLDemo

Теперь установим пакет Hot Chocolate:

dotnet add package HotChocolate.AspNetCore
dotnet add package HotChocolate.AspNetCore.Playground

Пакет HotChocolate.AspNetCore добавляет middleware для обработки GraphQL-запросов, а HotChocolate.AspNetCore.Playground предоставляет встроенную IDE (GraphQL Playground) для тестирования.

Конфигурация Startup

Отредактируйте файл Program.cs (или Startup.cs для .NET 5 и ниже). Добавим базовую конфигурацию:

var builder = WebApplication.CreateBuilder(args);

// Добавляем сервисы GraphQL
builder.Services
    .AddGraphQLServer()
    .AddQueryType<Query>()
    .AddMutationType<Mutation>(); // добавим позже

var app = builder.Build();

// Добавляем middleware
app.UseRouting();
app.MapGraphQL(); // эндпоинт /graphql
app.MapGraphQLPlayground(); // Playground доступен по /playground

app.Run();

Обратите внимание: Query и Mutation — это классы, которые мы создадим далее. Пока оставим только Query.

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

Модель Book

Создадим простую модель книги. Добавьте файл Models/Book.cs:

namespace GraphQLDemo.Models;

public class Book
{
    public int Id { get; set; }
    public string Title { get; set; } = string.Empty;
    public string Author { get; set; } = string.Empty;
    public int Year { get; set; }
    public decimal Price { get; set; }
}

Класс Query

Теперь создадим класс Query, который будет содержать методы для получения данных. Добавьте файл GraphQL/Query.cs:

using GraphQLDemo.Models;

namespace GraphQLDemo.GraphQL;

public class Query
{
    // Временное хранилище данных (в реальном проекте — БД)
    private static readonly List<Book> Books = new()
    {
        new Book { Id = 1, Title = "Война и мир", Author = "Лев Толстой", Year = 1869, Price = 29.99m },
        new Book { Id = 2, Title = "Преступление и наказание", Author = "Федор Достоевский", Year = 1866, Price = 24.99m },
        new Book { Id = 3, Title = "Мастер и Маргарита", Author = "Михаил Булгаков", Year = 1967, Price = 19.99m }
    };

    // Запрос: получить все книги
    public IQueryable<Book> GetBooks() => Books.AsQueryable();

    // Запрос: получить книгу по ID
    public Book? GetBookById(int id) => Books.FirstOrDefault(b => b.Id == id);
}

Методы, возвращающие данные, называются resolver'ами. Hot Chocolate автоматически определяет их имена и типы. Обратите внимание: названия методов в C# преобразуются в camelCase в GraphQL (например, GetBooks станет getBooks).

Тестирование в Playground

Запустите приложение (dotnet run) и откройте браузер по адресу http://localhost:5000/playground. Введите следующий запрос:

query {
  books {
    id
    title
    author
    year
  }
}

Вы получите список книг. Попробуйте запросить только title и author — вы увидите, что лишние поля не возвращаются. Это и есть магия GraphQL.

3. Мутации: добавление и изменение данных

Мутации (mutations) — это операции, которые изменяют данные на сервере (аналог POST, PUT, DELETE в REST). Создадим класс Mutation в файле GraphQL/Mutation.cs:

using GraphQLDemo.Models;

namespace GraphQLDemo.GraphQL;

public class Mutation
{
    // Временное хранилище (в реальном проекте — инжекция через DI)
    private static readonly List<Book> Books = new()
    {
        new Book { Id = 1, Title = "Война и мир", Author = "Лев Толстой", Year = 1869, Price = 29.99m },
        new Book { Id = 2, Title = "Преступление и наказание", Author = "Федор Достоевский", Year = 1866, Price = 24.99m }
    };

    private static int _nextId = 3;

    // Мутация: добавить книгу
    public Book AddBook(string title, string author, int year, decimal price)
    {
        var book = new Book
        {
            Id = _nextId++,
            Title = title,
            Author = author,
            Year = year,
            Price = price
        };
        Books.Add(book);
        return book;
    }

    // Мутация: обновить цену книги
    public Book? UpdateBookPrice(int id, decimal newPrice)
    {
        var book = Books.FirstOrDefault(b => b.Id == id);
        if (book != null)
        {
            book.Price = newPrice;
        }
        return book;
    }
}

Не забудьте зарегистрировать Mutation в Program.cs (мы уже добавили строку .AddMutationType<Mutation>()). Теперь перезапу

Блоги

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