GraphQL API с C#: пошаговый туториал для начинающих

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

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

Начать курс

Введение в GraphQL с C#

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

Мы пройдем путь от установки до реализации запросов, мутаций и подписок. К концу статьи вы сможете самостоятельно развернуть GraphQL-сервер на C# и интегрировать его в свои проекты.

1. Установка и настройка проекта

Для начала создадим новый проект ASP.NET Core. Убедитесь, что у вас установлена среда .NET SDK (версия 6.0 или выше). Откройте терминал или командную строку и выполните:

dotnet new web -n GraphQLDemo
cd GraphQLDemo

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

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

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

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

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

var app = builder.Build();

// Подключаем middleware GraphQL
app.MapGraphQL();

// Добавляем Playground для тестирования
app.UsePlayground();

app.Run();

Теперь создадим простой класс Query в отдельном файле Query.cs:

public class Query
{
    public string Hello() => "Привет, мир GraphQL!";
}

Запустите проект командой dotnet run и откройте браузер по адресу http://localhost:5000/graphql. Вы увидите интерфейс Playground, где можно выполнить запрос:

{
  hello
}

Ответ: { "data": { "hello": "Привет, мир GraphQL!" } }

2. Создание типов и запросов

GraphQL строго типизирован. В C# мы используем классы для определения типов. Создадим модель Book и Author:

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

public class Author
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Book> Books { get; set; }
}

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

public class Query
{
    private static List<Author> _authors = new()
    {
        new Author
        {
            Id = 1,
            Name = "Лев Толстой",
            Books = new List<Book>
            {
                new Book { Id = 1, Title = "Война и мир", Author = null },
                new Book { Id = 2, Title = "Анна Каренина", Author = null }
            }
        },
        new Author
        {
            Id = 2,
            Name = "Фёдор Достоевский",
            Books = new List<Book>
            {
                new Book { Id = 3, Title = "Преступление и наказание", Author = null }
            }
        }
    };

    public List<Author> GetAuthors() => _authors;

    public Author GetAuthor(int id) => 
        _authors.FirstOrDefault(a => a.Id == id);
    
    public List<Book> GetBooks() => 
        _authors.SelectMany(a => a.Books).ToList();
}

Обратите внимание: мы не настраивали явно типы — Hot Chocolate автоматически генерирует схему на основе классов C#. Теперь можно выполнять запросы:

{
  authors {
    id
    name
    books {
      title
    }
  }
}

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

3. Реализация мутаций (изменение данных)

Мутации в GraphQL позволяют изменять данные. Создадим класс Mutation:

public class Mutation
{
    public Book AddBook(string title, int authorId)
    {
        var author = Query._authors.FirstOrDefault(a => a.Id == authorId);
        if (author == null)
            throw new GraphQLException("Автор не найден");

        var book = new Book
        {
            Id = Query._authors.SelectMany(a => a.Books).Max(b => b.Id) + 1,
            Title = title,
            Author = author
        };
        author.Books.Add(book);
        return book;
    }
}

Зарегистрируйте мутацию в Program.cs:

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

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

mutation {
  addBook(title: "Идиот", authorId: 2) {
    id
    title
    author {
      name
    }
  }
}

Ответ вернет созданную книгу с данными автора. Обработка ошибок (например, если автор не найден) осуществляется через GraphQLException.

4. Подписки (real-time обновления)

Подписки позволяют клиентам получать обновления в реальном времени через WebSocket. Добавим подписку на добавление новой книги:

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

// Расширяем Mutation:
public class Mutation
{
    private readonly ITopicEventSender _eventSender;

    public Mutation(ITopicEventSender eventSender)
    {
        _eventSender = eventSender;
    }

    public async Task<Book> AddBook(string title, int authorId)
    {
        // ... код создания книги ...
        await _eventSender.SendAsync("BookAdded", book);
        return book;
    }
}

Зарегистрируйте подписку в Program.cs:

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

Подписка выполняется через WebSocket:

subscription {
  onBookAdded {
    id
    title
    author {
      name
    }
  }
}

Теперь, когда кто-то добавит книгу через му

Блоги

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