Ответ
GraphQL — это язык запросов для API и среда выполнения для обработки этих запросов с использованием существующих данных. Он позволяет клиенту точно указать, какие данные ему нужны.
Ключевые отличия от REST:
| Аспект | REST | GraphQL |
|---|---|---|
| Эндпоинты | Множество эндпоинтов для разных ресурсов (/users, /posts) |
Обычно один эндпоинт (/graphql) для всех запросов |
| Получение данных | Структура ответа определяется сервером. Часто приводит к over-fetching (получение лишних данных) или under-fetching (необходимость делать доп. запросы) | Клиент запрашивает только нужные поля, получая предсказуемый результат |
| Типизация | Не встроена в стандарт. Используются внешние спецификации, например, OpenAPI (Swagger) | Строгая система типов встроена в схему (Schema Definition Language, SDL), что обеспечивает самодокументируемость API |
| HTTP-методы | Использует разные методы (GET, POST, PUT, DELETE) для разных операций | В основном использует POST для всех операций (включая чтение) |
Проблема N+1 в GraphQL
Это распространенная проблема, когда для получения списка из N элементов и их связанных данных выполняется N+1 запрос к базе данных. Она решается с помощью паттерна Dataloader, который группирует множество запросов в один пакетный запрос.
Пример простого GraphQL-сервера (Python/Graphene):
import graphene
from flask import Flask
from flask_graphql import GraphQLView
# Определение схемы: какие запросы (Query) может выполнять клиент
class Query(graphene.ObjectType):
hello = graphene.String(name=graphene.String(default_value="World"))
# Функция-резолвер, которая возвращает данные для поля 'hello'
def resolve_hello(self, info, name):
return f"Hello, {name}!"
schema = graphene.Schema(query=Query)
app = Flask(__name__)
app.add_url_rule('/graphql', view_func=GraphQLView.as_view('graphql', schema=schema, graphiql=True))
if __name__ == '__main__':
app.run()
Когда использовать GraphQL?
- Когда у вас много разных клиентов (веб, мобильные) с разными требованиями к данным.
- В сложных системах со множеством связанных сущностей.