Вступ до 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 зазирніть у офіційну документацію.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ