Подзаголовок: Кто кого: REST — старый добрый мастер запросов или GraphQL — свежий хит программистского TikTok'а?
🧐 Введение: Зачем нам это всё?
Если ты делаешь бекенд, тебе 100% нужно общаться с фронтендом. И тут ты стоишь перед выбором:
- REST API — «по-старинке»: чёткие маршруты, чёткие ответы.
- GraphQL — «по-новому»: один эндпоинт, запросы как хочешь, ответ как заказывал.
Оба варианта хороши, но для разных задач.
🔍 REST и GraphQL: коротко и ясно
🔧 Реализация REST API на Flask
Создадим API для пользователей.
users.json — представим, что это наша база данных:
[
{ "id": 1, "name": "Alice" },
{ "id": 2, "name": "Bob" }
]
📁 app.py (REST)
from flask import Flask, jsonify, request
app = Flask(__name__)
users = [
{"id": 1, "name": "Alice"},
{"id": 2, "name": "Bob"}
]
@app.route('/users', methods=['GET'])
def get_users():
return jsonify(users)
@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
user = next((u for u in users if u["id"] == user_id), None)
if user:
return jsonify(user)
return jsonify({"error": "User not found"}), 404
@app.route('/users', methods=['POST'])
def add_user():
data = request.get_json()
new_user = {"id": len(users)+1, "name": data["name"]}
users.append(new_user)
return jsonify(new_user), 201
if __name__ == '__main__':
app.run(debug=True)
📌 Всё по классике: GET, POST, маршруты, JSON. Всё чётко и понятно. Но... а если нам нужен только name, без id? REST так не умеет.
⚙️ Реализация GraphQL на Flask (с Flask-GraphQL)
Установим библиотеку:
pip install flask-graphql graphene
📁 graphql_app.py
from flask import Flask
from flask_graphql import GraphQLView
import graphene
class User(graphene.ObjectType):
id = graphene.Int()
name = graphene.String()
class Query(graphene.ObjectType):
users = graphene.List(User)
user = graphene.Field(User, id=graphene.Int(required=True))
def resolve_users(self, info):
return users
def resolve_user(self, info, id):
return next((u for u in users if u["id"] == id), None)
class CreateUser(graphene.Mutation):
class Arguments:
name = graphene.String(required=True)
user = graphene.Field(lambda: User)
def mutate(self, info, name):
new_user = {"id": len(users)+1, "name": name}
users.append(new_user)
return CreateUser(user=new_user)
class Mutation(graphene.ObjectType):
create_user = CreateUser.Field()
schema = graphene.Schema(query=Query, mutation=Mutation)
app = Flask(__name__)
app.add_url_rule(
'/graphql',
view_func=GraphQLView.as_view('graphql', schema=schema, graphiql=True)
)
users = [
{"id": 1, "name": "Alice"},
{"id": 2, "name": "Bob"}
]
if __name__ == '__main__':
app.run(debug=True)
🔍 Пример запроса в GraphiQL:
query {
users {
name
}
}
📌 Мы получим только имена пользователей. И можем запрашивать, что нужно, когда нужно.
💡 Реальные задачи и примеры
1. ✅ Получить всех пользователей (REST и GraphQL)
REST: GET /users
GraphQL:
query {
users {
id
name
}
}
2. 🔍 Получить пользователя по id
REST: GET /users/2
GraphQL:
query {
user(id: 2) {
name
}
}
3. 📝 Добавить нового пользователя
REST:
POST /users
{ "name": "Charlie" }
GraphQL:
mutation {
createUser(name: "Charlie") {
user {
id
name
}
}
}
4. 🧹 Избавиться от лишних данных
В REST ты получаешь весь объект.
В GraphQL ты сам говоришь: хочу только name. Вот где выигрывает экономия.
5. 🤖 Интеграция с фронтом (например, React)
GraphQL идеально сочетается с Apollo Client: ты пишешь query, и всё работает магически.
REST проще подключить "на коленке" через fetch.
⚖️ Что выбрать?
🔚 Заключение
REST или GraphQL — это не битва, а выбор инструмента под задачу. REST прост и ясен, GraphQL — гибок и мощен.
🔥 Хочешь продолжение: как сделать авторизацию в GraphQL или как связать с базой данных? Пиши, и будет вторая часть!