View-функции API
Запрос к API проходит такой путь:
urls.py — здесь настраивается маршрутизация API, описываются эндпоинты для ресурсов; Эндпоинтами в терминах REST API принято называть URL-адрес, идентифицирующий ресурс.
serializers.py — здесь данные преобразуются в JSON и обратно;
views.py — здесь идёт обработка параметров запроса, получение или запись данных, создание ответа.
Как и всегда в Django, в работе с API применяются Views: функции или классы. Классы могут быть низкого уровня (их пишут вручную) или «высокоуровневые»: в них заготовлены инструменты для решения типовых задач. Основная идея в том, что для решения экзотических задач применяют низкоуровневые классы, а если задача типичная (скажем, CRUD) — высокоуровневые.
Есть ещё так называемые мета-функции, или вьюсеты. Это очень мощный инструмент, ему будет посвящена отдельная тема нашего курса.
Token Authentication
Один из принципов построения REST — отсутствие состояния (stateless). Это значит, что каждый запрос к серверу должен содержать информацию о том, кто совершает этот запрос (информацию о пользователе). Сопоставление этих данных с учетными данными на сервере называется аутентификацией.
Рассмотрим самый простой способ аутентификации — по токену.
Для получения токена клиент посылает серверу запрос, передав логин и пароль. Если в базе данных существует такой пользователь и пароль совпадает, то в ответ клиент получает токен. При каждом последующем запросе к API проводится проверка: есть ли переданный с запросом токен в базе и какому пользователю он соответствует.
Для реализации этого механизма нужно выполнить несколько действий.
- Добавить приложение
'rest_framework.authtoken' в INSTALLED_APPS - В
settings.py объявить новый способ аутентификации TokenAuthentication и, одновременно, запретить доступ всем неаутентифицированным пользователям, установив значение IsAuthenticated для ключа DEFAULT_PERMISSION_CLASSES:
Скопировать кодPYTHON
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
]
}
Ограничение доступа настраивается с помощью пермишенов (англ. "permissions", разрешения). Мы поговорим о них подробно в следующем спринте, а пока просто подключите их к проекту.
Выполнить миграции, чтобы в базе данных создались поля для работы и хранения токена: python manage.py migrate
Добавить маршрут для получения токена:
Скопировать кодPYTHON
from rest_framework.authtoken import views
urlpatterns += [
path('api-token-auth/', views.obtain_auth_token)
]
В этом уроке вы будете работать в тренажере, поэтому миграции мы выполнили за вас.
Теперь можно отправить POST-запрос к адресу
api-token-auth/, передать в теле запроса поля
username и
password — и в ответ придёт заветный токен:
{
"token": "d31754b63d74f15b48aa91ac387f5115d0ba83d6"
}
Этот токен надо будет передавать в заголовке каждого запроса, в поле Authorization: Authorization: Token d31754b63d74f15b48aa91ac387f5115d0ba83d6
При успешной аутентификации TokenAuthentication вернёт такие данные:
request.user будет экземпляром пользователя.request.auth будет токеном (экземпляром rest_framework.authtoken.models.Token)
В ответ на неаутентифицированные запросы клиент получит отказ: ему в ответ придёт статус-код HTTP 401 Unauthorized:
{
"detail": "Authentication credentials were not provided."
}
View-функции
Чтобы создать view-функцию для API, нужно декорировать обычную view-функцию следующим образом: @api_view(<разрешенные HTTP-методы>) . Такая функция должна возвращать объект Response(<отправляемые данные>).
Рассмотрим пример. View-функция hello при GET-запросе возвращает ответ «Привет, мир!» в формате JSON. При POST-запросе она вернёт строку со включением полученных данных, если они были. При запросах другого типа, например, PUT, вернётся сообщение «Метод не разрешен» и статус-код ошибки "405 Method Not Allowed".
Скопировать кодPYTHON
from rest_framework.decorators import api_view
from rest_framework.response import Response
@api_view(['GET', 'POST'])
def hello(request):
if request.method == 'POST':
return Response({'message': f'Привет {request.data}'})
return Response({'message': 'Привет, мир!'})
Обычно в API создание нового объекта и запрос всех объектов реализуется в одной функции, а получение/изменение/удаление объекта — в другой. То есть весь функционал CRUD может быть реализован двумя view-функциями API.
Для удобства работы и отладки у DRF есть специальный браузерный API. Он позволяет совершать все виды запросов прямо из браузера, красиво и структурированно выводит объекты, поддерживает авторизацию. Используйте его для проверки работоспособности ваших эндпоинтов.
Существуют также другие мощные инструменты для удобной работы и тестирования API.
Например, консольный HTTPie и графический Postman. Потестируйте их, эти сервисы помогут вам в разработке.
Пришло время самостоятельно реализовать CRUD на Django REST Framework с помощью view-функций API.
Работайте с сериализатором так же, как с уже знакомыми вам формами. Вспомните методы is_valid(), save(), и delete() — и у вас всё получится!
Прежде чем вы отправитесь в бой, отметим ещё несколько важных моментов:
- View-функция обрабатывает только те запросы, которые вы указали в декораторе
@api_view(<разрешенные HTTP-методы>) - Данные приходят в объекте
request.data и передаются в конструктор сериализатора через именованный параметр data. - Необходимо вернуть клиенту правильный статус-код. Список кодов можно уточнить здесь.