Аббревиатура API расшифровывается как «Application Programming Interface» (интерфейс программирования приложений, программный интерфейс приложения).
Чтобы понять, как и каким образом API применяется в разработке и бизнесе, сначала нужно разобраться, как устроена «всемирная паутина».
WWW можно представить как огромную сеть связанных серверов, на которых и хранится каждая страница.
При введении в адресную строку браузера www.facebook.com
на удалённый сервер Facebook отправляется соответствующий запрос. Как только браузер получает ответ, то интерпретирует код и отображает страницу.
Каждый раз, когда пользователь посещает какую-либо страницу в сети, он взаимодействует с API удалённого сервера. API — это составляющая часть сервера, которая получает запросы и отправляет ответы.
Чем API отличается от привычных нам методов? Разница в формате запроса и ответа. Чтобы сгенерировать полную веб-страницу, браузер ожидает ответ на языке разметки HTML, в то время как API Google Календаря вернёт просто данные в формате вроде JSON.
Пользователь благодаря API получает возможность совершить действие, не покидая сайт компании.
Многие разработчики разносят приложение на несколько серверов, которые взаимодействуют между собой при помощи API. Серверы, которые выполняют вспомогательную функцию по отношению к главному серверу приложения, называются микросервисами.
Слово «application» (прикладной, приложение) может применяться в разных значениях. В контексте API оно подразумевает:
Разные части программы как-то общаются между собой. Они делают это на программном уровне, то есть на уровне API!
Это самый «простой» в использовании способ, потому что автор API, которое вызывается — разработчик.
Одна система дергает через api какой-то метод другой системы. Она может попытаться получить данные из другой системы. Или наоборот, отправить данные в эту систему.
Причины разные:
Если система предоставляет API, обычно проще дернуть его, чем делать то же самое через графический интерфейс. Тем более что вызов API можно сохранить в инструменте. Один раз сохранил — на любой базе применяешь, пусть даже она по 10 раз в день чистится.
Когда пользователь работает с GUI, на самом деле он тоже работает с API. Просто не знает об этом, ему это просто не нужно.
То есть когда пользователь открывает систему и пытается загрузить отчет, ему не важно, как работает система, какой там magic внутри. У него есть кнопочка «загрузить отчет», на которую он и нажимает. Пользователь работает через GUI (графический пользовательский интерфейс).
Django Rest Framework (DRF) — это библиотека, которая работает со стандартными моделями Django для создания гибкого и мощного API для проекта.
API DRF состоит из 3-х слоев: сериализатора, вида и маршрутизатора.
Модели Django интуитивно представляют данные, хранящиеся в базе, но API должен передавать информацию в менее сложной структуре. Хотя данные будут представлены как экземпляры классов Model, их необходимо перевести в формат JSON для передачи через API.
Сериализатор DRF производит это преобразование. Когда пользователь передает информацию (например, создание нового экземпляра) через API, сериализатор берет данные, проверяет их и преобразует в нечто, что Django может сложить в экземпляр модели.
Наиболее распространенной формой, которую принимает сериализатор DRF, является тот, который привязан непосредственно к модели Django:
class ThingSerializer(serializers.ModelSerializer):
class Meta:
model = Thing
fields = ('name', )
Сериализатор анализирует информацию в обоих направлениях (чтение и запись), тогда как ViewSet - это тот код, в котором определены доступные операции.
Наиболее распространенным ViewSet является ModelViewSet, который имеет следующие встроенные операции:
Создание экземпляра: create()
Получение / чтение экземпляра: retrieve()
Обновление экземпляра (все или только выбранные поля): update() или partial_update()
Уничтожение / Удаление экземпляра: destroy()
Список экземпляров (с разбивкой по страницам по умолчанию): list()
Каждая из этих функций может быть переопределена, если требуется другое поведение, но стандартная функциональность работает с минимальным кодом, а именно:
class ThingViewSet(viewsets.ModelViewSet):
queryset = Thing.objects.all()
И наконец, маршрутизаторы: они предоставляют верхний уровень API.
тобы избежать создания бесконечных URL-адресов вида: «списки», «детали» и «изменить», маршрутизаторы DRF объединяют все URL-адреса, необходимые для данного вида в одну строку для каждого ViewSet, например:
# Инициализация роутера DRF. Только один раз на файл urls.py
# из маршрутизаторов импорта rest_framework
router = routers.DefaultRouter()
# Регистрация ViewSet
router.register(r'thing', main_api.ThingViewSet)
Затем все ViewSet, которые зарегистрированны в маршрутизаторе, можно добавить к обычным url_patterns:
<kbd>url_patterns + = url (r '^', include (router.urls))</kbd>
Теперь через API можно получить данные точно так же, как и любые другие обычные страницы Django.
Установим библиотеки Django REST framework и django-cors-headers, для чего наберем команды:
pip install djangorestframework
pip install django-cors-headers
Сразу же создадим новое приложение api, в котором и реализуем функциональность веб-службы:
python manage.py startapp api
Добавим приложения rest_framework И corsheaders — Программные Ядра ТОЛЬКО
что установленных библиотек, а также только что созданное приложение api
в список зарегистрированных в проекте:
INSTALLED_APPS = [
...
'rest_framework',
'corsheaders',
'api.apps.ApiConfig',
]
Добавим в список зарегистрированных в проекте необходимый для работы посредник:
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
]
He забудем указать там же, в модуле settings.py пакета конфигурации, настройки,
разрешающие доступ к веб-службе с любого домена:
CORS_ORIGIN_ALLOW_ALL = True
CORS_URLS_REGEX = r'^/api/.*$'
Создадим в пакете приложения api модуль serializers.py. В нем сохраним код сериализатора BbSerializer, формирующего список объявлений.
from rest_framework import serializers
from main.models import Bb
class BbSerializer(serializers.ModelSerializer):
class Meta:
model = Bb
fields = ('id', 'title', 'content', 'price', 'created_at')
онтроллер, который будет выдавать список объявлений, реализуем в виде функции и назовем bbs().
from rest_framework.response import Response
from rest_framework.decorators import api_view
from main.models import Bb
from .serializers import BbSerializer
@api_view(['GET'])
def bbs(request):
if request.method == 'GET':
bbs = Bb.objects.filter(is_active=True)[:10]
serializer = BbSerializer(bbs, many=True)
return Response(serializer.data)
Откроем список маршрутов уровня проекта (модуль urls.py пакета конфигурации) и добавим маршрут, указывающий на приложение api:
urlpatterns = [
...
path('api/', include('api.urls')),
path('', include('main.urls')),
]
В пакете приложения api создадим модель urls.py, в который запишем список маршрутов уровня этого приложения.
from django.urls import path
from .views import bbs
urlpatterns = [
path('bbs/', bbs),
]
Сохраним код, запустим отладочный веб-сервер и попробуем получить список объявлений, перейдя по интернет-адресу http://localhost:8000/api/bbs/
. Если мы все сделали правильно, то увидим веб-представление, показывающее последние 10 объявлений, которые были оставлены посетителями сайта.
Занесем код сериализатора BbDetaiiserializer, выдающего сведения об объявлении в модуль serializers.py пакета приложения.
class BbDetailSerializer(serializers.ModelSerializer):
class Meta:
model = Bb
fields = ('id', 'title', 'content', 'price', 'created_at', 'contacts', 'image')
Контроллер назовем BbDetailView и реализуем в виде класса, производного от класса RetrieveAPIView. Его код, весьма компактный.
from rest_framework.generics import RetrieveAPIView
from .serializers import BbDetailSerializer
class BbDetailView(RetrieveAPIView):
queryset = Bb.objects.filter(is_active=True)
serializer_class = BbDetailSerializer
Добавим в список маршрутов уровня приложения маршрут, который укажет на наш
новый контроллер:
from .views import BbDetailView
urlpatterns = [
path('bbs/<int:pk>/', BbDetailView.as_view()),
path('bbs/', bbs),
]
Код сериализатора Commentserializer, который будет отправлять список комментариев и добавлять новый комментарий.
from main.models import Comment
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = ('bb', 'author', 'content', 'created_at')
од контроллера-функции comments(), выдающего список комментариев и добавляющего новый комментарий.
from rest_framework.decorators import permission_classes
from rest_framework.status import HTTP_201_CREATED, HTTP_400_BAD_REQUEST
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from main.models import Comment
from .serializers import CommentSerializer
@api_view(['GET', 'POST'])
@permission_classes((IsAuthenticatedOrReadOnly,))
def comments(request, pk):
if request.method == 'POST':
serializer = CommentSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=HTTP_201_CREATED)
else:
return Response(serializer.errors, status=HTTP_400_BAD_REQUEST)
else:
comments = Comment.objects.filter(is_active=True, bb=pk)
serializer = CommentSerializer(comments, many=True)
return Response(serializer.data)
Маршрут, который укажет на новый контроллер и который мы поместим в список уровня приложения, будет выглядеть так:
from .views import comments
urlpatterns = [
path('bbs/<int:pk>/comments/' , comments),
path('bbs/<int:pk>/', BbDetailView.as_view()),
]