Что ж, пришла пора объединить наши знания в единое целое и создать полноценный API с использованием всех пройденных концепций.
Часть 1: постановка задачи
Мы создаём API для управления библиотекой книг. Наш API должен:
- Позволять пользователям:
- Получать список всех книг;
- Искать книги по автору или названию;
- Получать подробную информацию о конкретной книге.
- Предоставлять администраторам возможность:
- Добавлять и редактировать книги;
- Удалять книги.
- Ограничивать действия на основе ролей:
- Только администратор может изменять данные.
Часть 2: подготовка модели и проекта
- Создание модели
Предположим, что в нашем проекте уже есть базовая модель для книги. Если её нет, добавим её:
# models.py
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=100)
published_date = models.DateField()
isbn = models.CharField(max_length=13, unique=True)
summary = models.TextField(blank=True, null=True)
def __str__(self):
return self.title
После добавления модели не забудьте выполнить миграции:
python manage.py makemigrations
python manage.py migrate
Часть 3: создание схемы для GraphQL
- Настройка
DjangoObjectType
Для работы с GraphQL мы используем библиотеку graphene-django. Убедитесь, что она установлена:
pip install graphene-django
Теперь создадим тип объекта для нашей модели Book:
# schema.py (в приложении, например, "library")
import graphene
from graphene_django.types import DjangoObjectType
from .models import Book
class BookType(DjangoObjectType):
class Meta:
model = Book
fields = ("id", "title", "author", "published_date", "isbn", "summary")
- Определение Query для чтения данных
Добавим возможность получать список книг и подробности о конкретной книге:
# schema.py
class Query(graphene.ObjectType):
all_books = graphene.List(BookType)
book_by_id = graphene.Field(BookType, id=graphene.Int(required=True))
def resolve_all_books(self, info):
return Book.objects.all()
def resolve_book_by_id(self, info, id):
try:
return Book.objects.get(pk=id)
except Book.DoesNotExist:
return None
Часть 4: мутации для управления данными
- Создание мутаций
Теперь добавим мутации для создания, обновления и удаления книг:
# schema.py
class CreateBook(graphene.Mutation):
book = graphene.Field(BookType)
class Arguments:
title = graphene.String(required=True)
author = graphene.String(required=True)
published_date = graphene.Date(required=True)
isbn = graphene.String(required=True)
summary = graphene.String()
def mutate(self, info, title, author, published_date, isbn, summary=None):
book = Book(
title=title,
author=author,
published_date=published_date,
isbn=isbn,
summary=summary
)
book.save()
return CreateBook(book=book)
class UpdateBook(graphene.Mutation):
book = graphene.Field(BookType)
class Arguments:
id = graphene.Int(required=True)
title = graphene.String()
author = graphene.String()
published_date = graphene.Date()
isbn = graphene.String()
summary = graphene.String()
def mutate(self, info, id, title=None, author=None, published_date=None, isbn=None, summary=None):
try:
book = Book.objects.get(pk=id)
if title:
book.title = title
if author:
book.author = author
if published_date:
book.published_date = published_date
if isbn:
book.isbn = isbn
if summary:
book.summary = summary
book.save()
return UpdateBook(book=book)
except Book.DoesNotExist:
return None
class DeleteBook(graphene.Mutation):
success = graphene.Boolean()
class Arguments:
id = graphene.Int(required=True)
def mutate(self, info, id):
try:
book = Book.objects.get(pk=id)
book.delete()
return DeleteBook(success=True)
except Book.DoesNotExist:
return DeleteBook(success=False)
- Подключение мутаций
Теперь добавим мутации к нашей схеме:
# schema.py
class Mutation(graphene.ObjectType):
create_book = CreateBook.Field()
update_book = UpdateBook.Field()
delete_book = DeleteBook.Field()
Часть 5: настройка аутентификации и разрешений
- Ограничение мутаций для администраторов
Добавим проверку роли пользователя внутри мутаций. Например:
# schema.py
def mutate(self, info, **kwargs):
user = info.context.user
if not user.is_authenticated or not user.is_staff:
raise Exception("Вы должны быть администратором, чтобы выполнять это действие!")
# Ваш код для изменения данных...
- Настройка GraphiQL
Чтобы протестировать наши запросы и мутации, убедимся, что GraphiQL включён. В settings.py добавьте:
GRAPHENE = {
"SCHEMA": "library.schema.schema", # Укажите путь до вашей схемы
"MIDDLEWARE": [
"graphene_django.debug.DjangoDebugMiddleware",
],
}
И настройте URL для GraphQL:
# urls.py
from django.urls import path
from graphene_django.views import GraphQLView
urlpatterns = [
path("graphql/", GraphQLView.as_view(graphiql=True)),
]
Часть 6: тестирование API
Пример запросов
- Получение всех книг:
query {
allBooks {
id
title
author
}
}
- Добавление книги:
mutation {
createBook(
title: "Война и мир"
author: "Лев Толстой"
publishedDate: "1869-01-01"
isbn: "978-5-389-07457-6"
summary: "Великий роман о жизни и судьбе человечества."
) {
book {
id
title
}
}
}
Теперь ваш GraphQL API готов! Вы создали полноценный API, который можно использовать в реальной разработке. 🌟 Вы молодцы!
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ