senior
Чем отличаются REST, GraphQL и gRPC? Когда что использовать?
REST, GraphQL и gRPC — три подхода к проектированию API, решающие разные задачи: REST ориентирован на ресурсы, GraphQL — на гибкие запросы клиента, gRPC — на высокопроизводительный RPC.
Сравнительная таблица
| Характеристика | REST | GraphQL | gRPC |
|---|---|---|---|
| Протокол | HTTP/1.1, HTTP/2 | HTTP/1.1, HTTP/2 | HTTP/2 |
| Формат данных | JSON, XML | JSON | Protocol Buffers (бинарный) |
| Схема/контракт | OpenAPI (опционально) | GraphQL Schema (обязательно) | Protobuf (.proto, обязательно) |
| Стиль | Ресурсо-ориентированный | Запросо-ориентированный | RPC (вызов процедур) |
| Количество endpoint-ов | Множество (по ресурсу) | Один (/graphql) |
Множество (по сервису/методу) |
| Over-fetching | Да | Нет (клиент выбирает поля) | Нет (строгий контракт) |
| Under-fetching | Да (нужны доп. запросы) | Нет (один запрос) | Да |
| Streaming | Нет (SSE, WebSocket отдельно) | Subscriptions (WebSocket) | Да (нативная поддержка) |
| Кэширование | Встроенное (HTTP-кэш) | Сложное (один endpoint) | Нет нативного |
| Производительность | Средняя | Средняя | Высокая |
Когда что использовать
| Сценарий | Рекомендация |
|---|---|
| Публичные API, CRUD | REST |
| Мобильные/браузерные клиенты | REST |
| Сложные UI с разнородными данными (дашборды) | GraphQL |
| Множество клиентов с разными потребностями | GraphQL |
| Межсервисное взаимодействие, высокая нагрузка | gRPC |
| Real-time, streaming | gRPC |
| Полиглотные архитектуры | gRPC |
Комбинированный подход (наиболее распространённый)
Пример
┌──────────────────┐
│ API Gateway │
│ (REST / GraphQL)│
└────────┬─────────┘
│
┌──────────────┼──────────────┐
│ │ │
┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐
│ Service A │ │ Service B │ │ Service C │
└─────┬─────┘ └─────┬─────┘ └─────┬─────┘
│ │ │
└──────────────┼──────────────┘
gRPC (внутри)
Примеры кода для каждого подхода
REST (Spring):
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public ResponseEntity<UserDto> getUser(@PathVariable Long id) {
return ResponseEntity.ok(userService.findById(id));
}
}
GraphQL (Spring):
@Controller
public class UserGraphQLController {
@QueryMapping
public User user(@Argument Long id) {
return userService.findById(id);
}
// Resolver для вложенного поля — загружается только если клиент запросил
@SchemaMapping(typeName = "User", field = "orders")
public List<Order> orders(User user) {
return orderService.findByUserId(user.getId());
}
}
gRPC:
@GrpcService
public class UserGrpcService extends UserServiceGrpc.UserServiceImplBase {
@Override
public void getUser(GetUserRequest request,
StreamObserver<UserResponse> responseObserver) {
User user = userService.findById(request.getId());
UserResponse response = UserResponse.newBuilder()
.setId(user.getId())
.setName(user.getName())
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
Частые ошибки
- Выбор GraphQL для простого CRUD — избыточная сложность.
- Использование REST для межсервисного взаимодействия с высокой нагрузкой — gRPC значительно эффективнее.
- N+1 проблема в GraphQL — без DataLoader вложенные поля вызывают лавину запросов к БД.
- Использование gRPC для публичного API — браузеры не поддерживают gRPC напрямую.
Как используется в 2026
- Большинство компаний используют гибридный подход: REST/GraphQL для внешних клиентов, gRPC для внутренней коммуникации.
- Spring Boot 3.x имеет встроенную поддержку GraphQL и gRPC.
- Connect RPC — новый протокол, совместимый с gRPC, но работающий через обычный HTTP/JSON.
На собеседовании: нужно чётко разграничить три подхода по назначению и привести примеры, когда какой использовать. Частая ошибка — говорить, что GraphQL заменяет REST. Это инструменты для разных задач, и в реальных системах они часто сосуществуют.