Введение в GraphQL API
Если REST API — это "шведский стол", где вы едите всё, что напихали в тарелку (даже если хотите всего лишь десерт), то GraphQL — это персонализированный шеф-повар, который готовит именно то, что вы заказали. А главное — без лишнего.
GraphQL — это язык запросов к API, разработанный Facebook в 2012 году и предоставленный в открытый доступ в 2015 году. Его главная цель — дать разработчикам возможность запроса только тех данных, которые им действительно нужны, минимизируя избыточность данных (overfetching) и нехватку данных (underfetching).
Основные преимущества GraphQL:
- Гибкие запросы: вы получаете ровно те данные, которые запрашиваете.
- Типизация данных: клиент знает структуру данных заранее.
- Единая точка входа: одно API для всех данных.
Отличия REST от GraphQL
REST и GraphQL используют кардинально разные подходы к взаимодействию клиента и сервера. Давайте разберём ключевые различия:
| Характеристика | REST | GraphQL |
|---|---|---|
| Запрос данных | Фиксированные маршруты для сущностей | Одиночный эндпоинт для всех данных |
| Формат ответа | Фиксированный (может содержать лишние данные) | Гибкий (возвращает только запрошенные данные) |
| Обновление данных | Разные эндпоинты для каждого действия | Использование мутаций |
| Документация | Swagger/мануалы | GraphQL schema (самодокументируемый) |
Пример REST-запроса:
GET /users/1
Response: {
"id": 1,
"name": "Alice",
"email": "alice@example.com",
"age": 30
}
Пример GraphQL-запроса:
query {
user(id: 1) {
name
email
}
}
Response: {
"data": {
"user": {
"name": "Alice",
"email": "alice@example.com"
}
}
}
Как работает GraphQL: запросы, мутации и подписки
GraphQL работает с тремя основными концепциями:
- Запросы (Query): для получения данных.
- Мутации (Mutation): для изменения данных (POST, PUT, DELETE в REST).
- Подписки (Subscription): для получения данных в реальном времени.
Рассмотрим пример структуры GraphQL-запроса:
query {
user(id: 1) {
name
projects {
title
deadline
}
}
}
Этот запрос вернёт пользователя с ID 1 и список его проектов (ограниченный только title и deadline).
Мутация:
mutation {
createUser(name: "Alice", email: "alice@example.com") {
id
name
email
}
}
Выбор библиотеки для работы с GraphQL в Python
Для работы с GraphQL в Python существует несколько популярных библиотек:
gql: минималистичная библиотека для отправки запросов.sgqlc: предоставляет статическую типизацию GraphQL-запросов.httpx: универсальное решение для отправки HTTP-запросов, также поддерживающее GraphQL.
Мы будем использовать httpx, так как вы уже знакомы с ним, и он идеально подходит для интеграции GraphQL в FastAPI.
Установка:
pip install httpx
Пример реализации GraphQL клиента с FastAPI
Давайте реализуем базовый клиент для работы с GraphQL, используя httpx.
Напишем эндпоинт, который отправляет GraphQL-запрос на внешний GraphQL API.
from fastapi import FastAPI, HTTPException
import httpx
app = FastAPI()
GRAPHQL_API_URL = "https://example.com/graphql" # Укажите реальный GraphQL API
@app.get("/user/{user_id}")
async def get_user(user_id: int):
query = """
query GetUser($id: Int!) {
user(id: $id) {
name
email
}
}
"""
variables = {"id": user_id}
async with httpx.AsyncClient() as client:
response = await client.post(
GRAPHQL_API_URL,
json={"query": query, "variables": variables},
)
if response.status_code != 200:
raise HTTPException(status_code=response.status_code, detail="GraphQL API Error")
return response.json()
Обратите внимание:
- Мы отправляем запрос через POST, передавая query и variables.
- Переменные позволяют передавать динамические данные в запрос.
Запустите приложение и протестируйте эндпоинт /user/1, чтобы получить данные пользователя.
Практическая интеграция с существующим GraphQL API
Теперь, для закрепления, интегрируемся с реальным публичным GraphQL API. Например, воспользуемся Countries GraphQL API, который возвращает данные о странах.
Пример кода
GRAPHQL_API_URL = "https://countries.trevorblades.com/"
@app.get("/country/{code}")
async def get_country(code: str):
query = """
query GetCountry($code: ID!) {
country(code: $code) {
name
native
capital
currency
}
}
"""
variables = {"code": code.upper()}
async with httpx.AsyncClient() as client:
response = await client.post(
GRAPHQL_API_URL,
json={"query": query, "variables": variables},
)
if response.status_code != 200:
raise HTTPException(status_code=response.status_code, detail="GraphQL API Error")
return response.json()["data"]["country"]
Запустите приложение и вызовите эндпоинт /country/US, чтобы получить данные о США. Вы увидите информацию о столице, валюте и официальном названии страны.
Улучшение интеграции: Валидация данных
Валидация данных — это ваш лучший друг. Ниже используем Pydantic для проверки ответа.
from pydantic import BaseModel
class CountryModel(BaseModel):
name: str
native: str
capital: str
currency: str
@app.get("/country/{code}", response_model=CountryModel)
async def get_country(code: str):
query = """
query GetCountry($code: ID!) {
country(code: $code) {
name
native
capital
currency
}
}
"""
variables = {"code": code.upper()}
async with httpx.AsyncClient() as client:
response = await client.post(
GRAPHQL_API_URL,
json={"query": query, "variables": variables},
)
if response.status_code != 200:
raise HTTPException(status_code=response.status_code, detail="GraphQL API Error")
data = response.json()["data"]["country"]
return CountryModel(**data)
Теперь FastAPI автоматически проверяет и документирует данные, возвращаемые из API.
На что обратить внимание при интеграции
- Обработка ошибок с GraphQL может быть сложнее, так как ошибки часто возвращаются в поле
errorsв JSON-ответе. Проверяйте его наличие! - Убедитесь, что ваш GraphQL-запрос соответствует схеме, иначе получите ошибку валидации.
Вот так вы можете начать интеграцию с GraphQL API в своих проектах.
Для полного изучения возможностей GraphQL, загляните в официальную документацию.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ