Implementando API REST com Django – parte 1

django-rest-1_abertura

Incrementando a “Agenda de Eventos” com a adição de uma API de REST para o projeto e desta vez, ao invés de implementá-la do zero, como no caso do exemplo com Bottle, optei por uma abordagem mais simples e usarei o Django REST framework que, literalmente, se encarregará de mapear meu modelo de dados e de construir todas as opções da API sozinho.

Instalação do Django REST framework

A parte mais simples do processo pois basta usar o pip

$ source py3/bin/activate
(py3) $ pip install djangorestframework
Collecting djangorestframework
Downloading https://files.pythonhosted.org/packages/1b/fe/fcebec2a9
8fbd1548da1c12ce8d7f634a02a9cce350833fa227a625ec624/djangorestframewo
rk-3.9.4-py2.py3-none-any.whl (911kB)
     |████████████████████████████████| 921kB 244kB/s 
Installing collected packages: djangorestframework
Successfully installed djangorestframework-3.9.4

Também é necessário editar o arquivo “./Agenda/settings.py”…

# Application definition
INSTALLED_APPS = [
    "events",
    "rest_framework",
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
]
...
REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS':
        'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10
}

A primeira é a inclusão do módulo propriamente duto na lista de aplicações instaladas e a outra, opcional, habilita a paginação e configura a quantidade de elementos listados por requisição.

Criando um serializador

O serializador permite que estruturas de dados complexas (como é o caso dos querysets), sejam convertidas para os tipos de dados padrão do Python e assim poderem ser montados como JSON ou mesmo XML. A ideia aqui é criar um serializador que se encarregará de trabalhar com os eventos cadastrados na agenda, assim é criado o arquivo “./events/serializers.py” com o seguinte conteúdo.

from rest_framework import serializers
from .models import Event

class EventSerializer(serializers.ModelSerializer):

    class Meta:
        model = Event
        fields = ("date", "event", "priority",)

Dentro da classe EventSerializer estão duas informações importantes, a primeira é o modelo de serializador a ser utilizado, neste caso a classe ModelSerializer  e a outra, em Meta, a referência ao modelo e seus campos¹.

(¹) Poderia ter usado “__all__” porém existe um campo aqui que é implícito, que é relação com os comentários (que ficará para a próxima parte).

Adicionando o serializador à visão

Uma vez criado o serializador, é necessário, adicioná-lo à visão em “./events/views.py”.

from django.core.paginator import Paginator, InvalidPage
from django.http import HttpResponse
...
from rest_framework import viewsets

from .models import Event, Comment
from .forms import EventForm, CommentForm
from .serializers import EventSerializer
...
# Create your views here.
class EventViewSet(viewsets.ModelViewSet):
    queryset = Event.objects.all()
    serializer_class = EventSerializer

A classe EventViewSet cuidará da ligação entre a classe definida no serializador, o modelo propriamente dito e também as visualizações necessárias para cada comando do REST.

Direcionando os acessos

Por último, ou quase último, o direcionamento dos acessos para a visão correspondente em “./events/urls.py”.

from django.urls import path, include
from rest_framework import routers
from . import views

router = routers.DefaultRouter()
router.register(r"events", views.EventViewSet)

urlpatterns = [
    path("api/v1/", include(router.urls)),
    ...
]

Neste caso os acessos à API estarão dentro da estrutura “/api/v1/”, você pode definir outro caminho, e tudo que chegar para “/api/v1/events/” utilizará os métodos da classe EventsViewSet.

Testando a API REST!

Com tudo devidamente salvo e o servidor em execução, acessar todos os eventos cadastrados.

$ curl 127.0.0.1:8000/api/v1/events/
{"count":6,"next":null,"previous":null,"results":[{"date":"2018-06-15
","event":"Evento para ficar na próxima página","priority":"1"},{"d
ate":"2018-05-18","event":"Compra do pó de café, açúcar e pão pa
ra o café da manhã","priority":"2"},{"date":"2018-05-18","event":"C
afé da manhã comunitário","priority":"0"},{"date":"2018-04-20","ev
ent":"Terceiro evento da agenda","priority":"3"},{"date":"2018-04-13"
,"event":"Segundo evento da agenda (editado)","priority":"1"},{"date"
:"2018-04-13","event":"Primeiro evento da agenda","priority":"0"}]}

Recuperar a informação apenas de um evento.

$ curl 127.0.0.1:8000/api/v1/events/3/
{"date":"2018-04-20","event":"Terceiro evento da agenda","priority":"
3"

Inserir um novo evento.

$ curl --header 'Content-Type: application/json -X POST' --data '{"da
te":"2019-06-02","priority":"0","event":"Evento via cURL"}' http://12
7.0.0.1:8000/api/v1/events/
{"date":"2019-06-02","event":"Evento via cURL","priority":"0"}

Ou mesmo apagá-lo…

 $ curl -X DELETE http://127.0.0.1:8000/api/v1/events/10/

E tudo isto sem a necessidade de modifcar a aplicação já existente, ao menos não para criar estas funcionalidades.

Fim desta parte

django-rest-1_interface-web

O Django REST framework implementa ainda uma interface que auxilia bastante na depuração e nos testes e que aparecerá automaticamente caso seja detectado que o acesso vem de um navegador web.

As alterações aqui estão disponíveis no repositório git do projeto (tag “api-rest”) e para a próxima parte os comentários serão adicionados na API, como há algumas considerações a serem feitas, preferi não incluí-los aqui…

Até!

Anúncios