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

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

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

Начать курс

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

В современной веб-разработке GraphQL становится всё более популярной альтернативой REST API. В отличие от REST, где каждый эндпоинт возвращает фиксированную структуру данных, GraphQL позволяет клиенту запрашивать именно те данные, которые ему нужны. В этом туториале мы создадим полноценный GraphQL API на C# (.NET) с использованием библиотеки Hot Chocolate. Вы узнаете, как настроить сервер, определить типы данных, реализовать запросы и мутации, а также добавить подписки для real-time обновлений.

Что такое GraphQL и почему стоит использовать его с C#?

GraphQL — это язык запросов для API, разработанный Facebook. Основные преимущества:

  • Гибкость запросов — клиент сам решает, какие поля получить
  • Единая точка входа — один эндпоинт для всех запросов
  • Сильная типизация — все типы данных строго определены
  • Отсутствие over-fetching и under-fetching — вы получаете ровно то, что запросили

В экосистеме .NET лучшей библиотекой для реализации GraphQL является Hot Chocolate. Она поддерживает все возможности спецификации GraphQL, включая запросы (queries), мутации (mutations) и подписки (subscriptions).

Подготовка проекта и установка зависимостей

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

dotnet new webapi -n GraphQLDemo
cd GraphQLDemo

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

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

Создадим модель данных для нашего API. Допустим, мы будем работать с книгами и авторами. Создайте папку Models и добавьте в неё классы:

// Models/Author.cs
public class Author
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<Book> Books { get; set; }
}

// Models/Book.cs
public class Book
{
    public int Id { get; set; }
    public string Title { get; set; }
    public int AuthorId { get; set; }
    public Author Author { get; set; }
}

Создание GraphQL схемы и резолверов

В GraphQL ключевыми компонентами являются типы, запросы (Query) и мутации (Mutation). Создадим папку GraphQL и добавим в неё файлы:

// GraphQL/Query.cs
public class Query
{
    public IQueryable<Book> GetBooks([Service] ApplicationDbContext context)
    {
        return context.Books.Include(b => b.Author);
    }

    public Book GetBook(int id, [Service] ApplicationDbContext context)
    {
        return context.Books.Include(b => b.Author).FirstOrDefault(b => b.Id == id);
    }

    public IQueryable<Author> GetAuthors([Service] ApplicationDbContext context)
    {
        return context.Authors.Include(a => a.Books);
    }
}

// GraphQL/Mutation.cs
public class Mutation
{
    public async Task<Book> AddBook(string title, int authorId, [Service] ApplicationDbContext context)
    {
        var book = new Book { Title = title, AuthorId = authorId };
        context.Books.Add(book);
        await context.SaveChangesAsync();
        return book;
    }

    public async Task<Author> AddAuthor(string name, [Service] ApplicationDbContext context)
    {
        var author = new Author { Name = name };
        context.Authors.Add(author);
        await context.SaveChangesAsync();
        return author;
    }
}

Теперь зарегистрируем эти классы в Program.cs:

// Program.cs
var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddDbContext<ApplicationDbContext>(options =>
        options.UseInMemoryDatabase("GraphQLDemo"))
    .AddGraphQLServer()
    .AddQueryType<Query>()
    .AddMutationType<Mutation>()
    .AddFiltering()
    .AddSorting();

var app = builder.Build();

app.MapGraphQL();
app.UsePlayground();

app.Run();

Обратите внимание на методы AddFiltering() и AddSorting() — они добавляют возможности фильтрации и сортировки прямо в GraphQL запросы.

Настройка базы данных и начальных данных

Добавим контекст базы данных и сидер для тестовых данных:

// Data/ApplicationDbContext.cs
public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }

    public DbSet<Book> Books { get; set; }
    public DbSet<Author> Authors { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Book>()
            .HasOne(b => b.Author)
            .WithMany(a => a.Books)
            .HasForeignKey(b => b.AuthorId);
    }
}

// Data/DataSeeder.cs
public static class DataSeeder
{
    public static void Seed(ApplicationDbContext context)
    {
        if (context.Authors.Any()) return;

        var authors = new List<Author>
        {
            new Author { Id = 1, Name = "Лев Толстой" },
            new Author { Id = 2, Name = "Фёдор Достоевский" }
        };

        var books = new List<Book>
        {
            new Book { Id = 1, Title = "Война и мир", AuthorId = 1 },
            new Book { Id = 2, Title = "Анна Каренина", AuthorId = 1 },
            new Book { Id = 3, Title = "Преступление и наказание", AuthorId = 2 }
        };

        context.Authors.AddRange(authors);
        context.Books.AddRange(books);
        context.SaveChanges();
    }
}

Добавим вызов сидера в Program.cs:

// Program.cs (дополнение)
using var scope = app.Services.CreateScope();
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
DataSeeder.Seed(context);

Запросы, мутации и подписки на практике

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

Базовый запрос (Query):

query {
  books {
    title
    author {
      name
    }
  }
}

Запрос с фильтрацией:

query {
  books(where: { title: { contains: "Война" } }) {
    id
    title
    author {
      name
    }                

Блоги

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