API на C#: REST, GraphQL и gRPC — как выбрать и не пожалеть

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

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

Начать курс

Введение: API — это не страшно, а очень удобно

Представьте, что вы заказываете пиццу. Вы звоните в ресторан, диктуете адрес и состав — и через 30 минут курьер у двери. API в программировании работает точно так же: это тот самый «телефонный звонок», с помощью которого одна программа общается с другой. Только вместо голоса — HTTP-запросы, а вместо пиццы — данные.

В мире C# разработки API — это база. Любой современный проект, будь то веб-приложение, мобильный бэкенд или корпоративный сервис, так или иначе «дёргает» внешние сервисы. И тут встаёт главный вопрос: какой протокол выбрать? REST, GraphQL или gRPC? Каждый из них хорош по-своему, но каждый — для своей задачи.

В этой статье мы разберём работу с API на C# на реальных примерах. Вы узнаете, как отправлять HTTP-запросы, как подружить C# с GraphQL и gRPC, и, главное — поймёте, когда что использовать. Поехали!


1. REST API на C#: классика, которая не стареет

REST (Representational State Transfer) — это архитектурный стиль, который уже много лет остаётся стандартом де-факто. Простой, понятный, работает поверх HTTP. Если вы когда-либо писали код, который отправляет GET или POST запросы — вы уже работали с REST.

Как отправлять REST-запросы в C#

В C# для работы с REST чаще всего используют класс HttpClient. Он встроен в .NET и умеет всё: от простых GET-запросов до сложных POST с JSON-телом.

Вот как выглядит типичный запрос к REST API на C#:

using System;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        using HttpClient client = new HttpClient();
        client.BaseAddress = new Uri("https://api.example.com/");
        
        HttpResponseMessage response = await client.GetAsync("users/1");
        if (response.IsSuccessStatusCode)
        {
            string json = await response.Content.ReadAsStringAsync();
            Console.WriteLine(json);
        }
    }
}

Коротко и ясно. HttpClient живёт долго, поэтому его обычно создают один раз и переиспользуют (в реальных проектах — через DI-контейнер).

Когда REST — ваш выбор

  • Вы пишете публичное API для веба или мобильных приложений.
  • Клиенты — браузеры, мобильные устройства, IoT.
  • Вам нужна простота и кэширование на уровне HTTP.

Минусы REST: избыточность данных (часто приходит больше, чем нужно) и проблема N+1 запросов, когда для получения связанных данных приходится делать несколько вызовов.


2. GraphQL на C#: запрашивай только то, что нужно

GraphQL — это язык запросов, созданный Facebook. Его главная фишка: клиент сам решает, какие поля ему нужны. Никакой лишней информации, никаких десятков эндпоинтов — один запрос, один ответ.

Отправляем GraphQL-запрос из C#

Для работы с GraphQL на C# можно использовать HttpClient напрямую, но удобнее взять библиотеку GraphQL.Client (NuGet-пакет GraphQL.Client).

Пример запроса к GraphQL API:

using System;
using System.Threading.Tasks;
using GraphQL;
using GraphQL.Client.Http;
using GraphQL.Client.Serializer.Newtonsoft;

class Program
{
    static async Task Main(string[] args)
    {
        using var client = new GraphQLHttpClient("https://api.example.com/graphql", new NewtonsoftJsonSerializer());

        var request = new GraphQLRequest
        {
            Query = @"
            {
                user(id: 1) {
                    name
                    email
                    posts {
                        title
                    }
                }
            }"
        };

        var response = await client.SendQueryAsync<dynamic>(request);
        Console.WriteLine(response.Data);
    }
}

Обратите внимание: в одном запросе мы получили и пользователя, и его посты. В REST для этого пришлось бы делать два запроса или использовать сложные вложенные эндпоинты.

Когда GraphQL выигрывает

  • Сложные, глубоко вложенные данные (соцсети, каталоги).
  • Мобильные приложения, где каждый килобайт на счету.
  • Микросервисная архитектура: один GraphQL-шлюз объединяет данные из нескольких сервисов.

Минусы GraphQL: сложность кэширования, более высокая нагрузка на сервер (парсинг запросов), крутая кривая обучения для бэкенд-разработчиков.


3. gRPC на C#: скорость и строгость

gRPC — это протокол от Google, основанный на HTTP/2 и Protocol Buffers. Он не шутит: бинарный формат, строгие контракты, стриминг в обе стороны. Если REST — это велосипед, а GraphQL — гоночный автомобиль, то gRPC — это реактивный истребитель.

Как работать с gRPC в C#

Сначала нужно определить контракт в файле .proto:

syntax = "proto3";

service UserService {
    rpc GetUser (UserRequest) returns (UserResponse);
}

message UserRequest {
    int32 id = 1;
}

message UserResponse {
    string name = 1;
    string email = 2;
}

Затем сгенерировать код (это делает Visual Studio или dotnet build с пакетом Grpc.Tools). А дальше — вызывать сервис как обычный метод:

using Grpc.Net.Client;
using GrpcGreeterClient;

using var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new UserService.UserServiceClient(channel);

var reply = await client.GetUserAsync(new UserRequest { Id = 1 });
Console.WriteLine($"Name: {reply.Name}, Email: {reply.Email}");

Всё строго, типизированно, без JSON-сериализации. Работает молниеносно.

Где gRPC незаменим

  • Внутренние микросервисы (высокая производительность).
  • Системы реального времени (стриминг, чаты, лайв-данные).
  • IoT и мобильные устройства (экономия трафика).

Минусы gRPC: не поддерживается браузерами напрямую (требуется gRPC-Web), сложнее в отладке (бинарный трафик), жёсткие контракты — любое изменение требует перегенерации кода.


4. REST vs GraphQL vs gRPC: сводная таблица

Блоги

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

Критерий REST GraphQL gRPC