Olá, meu nome é Laís Urano, sou instrutora na Escola de Programação da Alura e vou acompanhar você neste curso de Django REST Framework.
Audiodescrição: Laís Urano se identifica como uma mulher parda. Possui olhos castanhos, cabelos cacheados e volumosos, também castanhos, com mechas azuis. Possui piercing no nariz e usa batom escuro. No corpo, utiliza uma camiseta verde oliva e um colar dourado. Atrás dela, os estúdios da Alura, onde há uma parede lisa e uma estante à direita, iluminadas em tons de verde e azul.
Este conteúdo é para quem deseja aprofundar conhecimentos sobre desenvolvimento de APIs com Python e Django REST Framework.
Será necessário ter conhecimento em Python e em Django. Além disso, este curso é uma continuação direta de dois cursos da Formação de Django REST Framework. Portanto, é importante estar familiarizado com os projetos anteriores dessa formação.
Veremos tudo isso no projeto de uma API de escola. Vamos começar?
Nos cursos anteriores, trabalhamos no desenvolvimento de uma API de uma escola que possui estudantes, cursos e matrículas. Todo o conteúdo que precisávamos desenvolver estava em cartões no Trello do projeto.
Desenvolvemos a API, adicionamos autenticações, validações, filtros, versionamento e diversos outros pontos. Agora, vamos continuar esse projeto, focando em outros pontos importantes para o desenvolvimento da API.
O primeiro cartão no backlog, chamado "Ordenação", indica a ordem na qual vamos começar. Mas antes, vamos revisar a API Root, a rota, para ver como ela está.
Acessando a página da API Root no navegador, notaremos três rotas: /estudantes
, /cursos
e /matriculas
.
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"estudantes": "http://127.0.0.1:8000/estudiantes/",
"cursos": "http://127.0.0.1:8000/cursos/",
"matriculas": "http://127.0.0.1:8000/matriculas/"
}
Podemos clicar em cada rota para acessá-la e verificar os estudantes e cursos que cadastramos. Já na rota de matrícula, veremos campos para cadastrar qualquer estudante.
Nessa rota, cadastraremos a Alícia no período matutino, no curso CPOO1.
Com login feito, essa matrícula cadastrada, e vendo que conseguimos acessar as rotas, podemos acessar o VS Code, em cujo terminal está rodando o servidor.
No terminal do VS Code, temos uma mensagem de aviso, de lista não ordenada (UnorderedObjectListWarning
), indicando que podemos apresentar resultados inconsistentes, devido ao fato desse modelo não estar ordenado quando o recebemos.
… UnorderedObjectListWarning: Pagination may yield to inconsistent results with an unordered object_list …
Acessaremos o explorador lateral para acessar o arquivo views.py
, dentro da pasta "escola". Em seu interior, há várias classes com viewset
s de estudante, curso, matrícula e todos os outros que definimos.
Na primeira linha de cada viewset
, definimos o queryset
, que está capturando os objetos do modelo. Nesse momento, não ordenamos esses objetos, apenas os capturamos.
Entretanto, por padrão, a API ordena tudo por ID. Acessando a API no navegador e entrando na rota /estudantes
, observaremos cada pessoa estudante ordenada por ID.
Na parte superior direita da página com a rota de estudantes, também adicionamos um botão de filtro. Clicando nele, vemos uma janela na qual é possível ordenar por nome, na ordem ascendente ou na ordem descendente.
Clicaremos na opção "nome - ascendente", impedindo que ele ordene por ID e resolvendo o problema.
A mensagem que recebemos não indica um erro, mas sim um aviso, informando que não estamos garantindo essa ordenação por ID e estamos esperando que a própria API faça isso para nós. Portanto, precisamos indicar no viewset
, no qual determinamos como os dados são capturados, que ele será ordenado também. Precisamos mostrar uma lista ordenada de objetos.
Ao voltar para o Trello do projeto e acessar o cartão "Ordenação", no backlog, podemos ler as regras que temos que implementar:
Regras:
- Todos os objetos de modelos capturados em suas respectivas ViewSets precisam ser ordenados por:
> * Estudante:
>
> * campo `id`;
>
> * Curso:
>
> * campo `id`;
>
> * Matrícula:
>
> * campo `id`;
Como podemos garantir essa ordenação?
No navegador, abriremos uma nova guia e pesquisaremos por "queryset api order".
queryset api order
Clicaremos no primeiro link para acessar a documentação do Django.
Recomendamos digitar e pesquisar essas informações em inglês, porque é mais fácil de achar. Mesmo existindo a possibilidade de tradução, muitos desses conteúdos não são traduzidos.
Dentro dessa página, abriremos o campo de pesquisa com "Ctrl+F" e pesquisaremos a palavra "order".
order
Pressionaremos "Enter" até achar a seção do método orderBy
. Esta informa que o orderBy
recolhe informações da opção ordering
do Meta
.
Esse Meta
deve ser definido na classe do Serializer
, mas não fizemos isso nos Serializers
. Mesmo assim, caso não definamos, ele informa que capturará as informações direto do banco de dados, de acordo com o que foi armazenado.
Nesse caso, como os dados são armazenados por ID, ele está ordenando por ID.
Como poderemos informar a ordem no viewset
, caso não tenhamos informado no ordering
do Serializer
? Podemos adicionar o método orderBy
ao capturar esse objeto para retornar o parâmetro que usaremos para ordenar - neste caso, o ID.
Dessa forma, ele ordenará por essas informações.
orderBy()
Voltando ao VS Code, no arquivo views.py
, faremos exatamente esse processo. Fecharemos a aba lateral do explorador para focar melhor no projeto.
Entre as chaves da classe EstudanteViewSet
, acessaremos o final da linha do queryset
de estudantes e adicionar .orderBy()
conectado ao Estudante.objects.all()
. Entre os parênteses, digitaremos o id
, entre aspas duplas.
views.py
:
class EstudanteViewSet(viewsets.ModelViewSet):
queryset = Estudante.objects.all().order_by("id")
# Código omitido
Isso ordenará as pessoas estudantes por ID.
Copiaremos esse .orderBy("id")
e colaremos no viewset
s das outras classes.
class CursoViewSet(viewsets.ModelViewSet):
queryset = Curso.objects.all().order_by("id")
# Código omitido
class MatriculaViewSet(viewsets.ModelViewSet):
queryset = Matricula.objects.all().order_by("id")
# Código omitido
Nos viewset
s de ListaMatriculaEstudante
e ListaMatriculaCurso
já estamos capturando a informação diretamente. Entretanto, para garantir que também haverá essa informação, colocaremos esse .orderBy()
no queryset
delas. Assim, caso precise ordenar, ela conseguirá capturar os dados ordenados.
class ListaMatriculaEstudante(generics.ListAPIView):
def get_queryset(self):
queryset = Matricula.objects.filter(estudante_id=self.kwargs['pk']).order_by("id")
# Código omitido
class ListaMatriculaCurso(generics.ListAPIView):
def get_queryset(self):
queryset = Matricula.objects.filter(curso_id=self.kwargs['pk']).order_by("id")
# Código omitido
Voltando ao terminal com "Ctrl+J", podemos confirmar que essa mensagem de aviso não está mais aparecendo. No navegador, fecharemos a guia da documentação do Django REST e acessaremos novamente a rota de estudantes na guia da aplicação. Recarregaremos a página para conseguir acessar.
Em seguida, se voltarmos ao terminal do VS Code, constataremos que foi possível acessar essa rota sem a mensagem de aviso anterior.
Voltando ao Trello, verificaremos os outros pontos que precisam ser implementados na API. Após passar o cartão "Ordenação" para a coluna "FINALIZADO", trabalharemos na limitação das requisições de rota da API.
Até o momento, podemos acessar qualquer rota da API quantas vezes quisermos, com a única condição de estarmos com o login feito. No entanto, essa quantidade ilimitada de acessos pode causar um problema para o sistema.
Vamos imaginar que várias pessoas estão tentando acessar esse sistema, mas não temos os recursos necessários para permitir que essa quantidade de pessoas acessem o sistema ao mesmo tempo, o que pode causar uma sobrecarga no servidor.
Além da sobrecarga, também temos que pensar no local em que esse sistema é hospedado. Se for em um serviço de nuvem, por exemplo, teremos recursos limitados, o que pode gerar um esgotamento ou até custos inesperados para essa quantidade de acesso.
Com essa falta de disponibilidade, o carregamento do site pode ficar lento ou o site pode "cair" (ficar fora do ar). Portanto, é importante implementar um limite de requisições para pessoas usuárias no sistema. Precisamos fazer isso agora.
Voltando ao Trello, na coluna "DESENVOLVENDO", abriremos o cartão "Limitar Requisições" que já verificamos. Ele nos informa algumas regras de API para pessoas usuárias logadas e anônimas.
Regras para a API:
- Usuários:
> * 50 requisições por dia
>
- Anônimos:
> * 20 requisições por dia
Regras específicas por rota:
Matrícula:
- Usuários:
50 requisições por dia
Anônimos:
5 requisições por dia
No caso, precisamos limitar o acesso de pessoas usuárias a 50 requisições por dia apenas e o acesso de anônimos a 20 requisições por dia.
Verificaremos essas regras específicas posteriormente, mas, primeiro, precisamos saber como implementar isso globalmente para a API.
Em uma nova guia do navegador, acessaremos a documentação. Já vimos esse esquema, então, pesquisaremos "Django REST Framework" e abriremos o link da documentação do Django REST.
Django REST Framework
No topo dessa página, acessaremos o menu "API Guide" e, na lista suspensa, clicaremos na seção "Throttling".
Essa seção informa, em sua introdução, que o throttling é similar às permissions e determinará se uma requisição tem a permissão de ser autorizada ou não. Podemos traduzir permissions para restrições, pois ele restringe o acesso.
Para configurar o throttling, rolaremos a página para baixo e acessaremos a seção de configuração do throttling. Ela informa que devemos utilizar um esquema que usamos anteriormente: colocar as informações dentro do REST Framework no arquivo settings.py
.
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '100/day',
'user': '1000/day'
}
No código acima, disponível na documentação, temos informações tanto para pessoas usuárias anônimas quanto para pessoas usuárias logadas. Também temos que definir a quantidade de rates (acessos permitidos).
Ele informa, como exemplo, 100 acessos por dia para pessoas usuárias anônimas e 1.000 acessos por dia para pessoas usuárias logadas. Também informa que podemos definir essas restrições por segundo, minuto, hora e dia, de acordo com o que temos interesse e com o que o sistema solicitar.
Copiaremos o conteúdo acima e colaremos essas informações no settings.py
. Abrindo o VS Code, pressionaremos "Ctrl+J" para fechar o terminal e "Ctrl+B" para abrir a aba lateral, na qual procuraremos o arquivo settings.py
dentro da pasta "setup".
No interior desse arquivo, entre as chaves do REST_FRAMEWORK
, acessaremos a última linha e adicionaremos uma vírgula para passar outra informação. Descendo uma linha, colaremos o código copiado.
Nesse código colado, precisamos modificar as informações para adicionar os dados solicitados para pessoas usuárias anônimas e logadas - 50 restrições por dia para pessoas usuárias logadas e apenas 20 para pessoas usuárias anônimas.
settings.py
:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_PAGINATION_CLASS': rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 20,
'DEFAULT_VERSIONING_CLASS': rest_framework.versioning.QueryParameterVersioning',
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '20/day',
'user': '50/day'
}
}
Também queremos entender como esse throttling está funcionando e atingindo esses pontos. Voltando à documentação aberta no navegador, acessaremos a seção "API Reference" para verificar o que são essas classes determinadas.
A subseção "AnonRateThrottle" informa que a classe anônima vai capturar pessoas usuárias não autenticadas pelo endereço de IP delas. Por isso, ele consegue identificar que uma pessoa usuária anônima, por exemplo, não conseguirá acessar em outro sites, porque estará utilizando no API ID.
Já a seção "UserRateThrottle" informa que uma chave será gerada para cada pessoa usuária autenticada, e por isso ele consegue identificar esses pontos.
Contudo, há um problema: para testar com pessoas usuárias anônimas, precisamos remover as autenticações primeiro. Além disso, há uma grande quantidade de volumes que podemos testar.
Como queremos verificar somente se esse código está funcionando, mudaremos as quantidades de restrições para 5 em pessoas usuárias logadas e 2 para anônimas.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_PAGINATION_CLASS': rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 20,
'DEFAULT_VERSIONING_CLASS': rest_framework.versioning.QueryParameterVersioning',
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '2/day',
'user': '5/day'
}
}
Testaremos para a pessoa usuária logada primeiro, que já temos.
Voltando à página da API REST no navegador, faremos o teste.
Ele considera as requisições a partir do momento que acessamos qualquer rota. Portanto, se acessarmos a rota /estudantes
e retornarmos à página anterior cinco vezes, ele contará cinco acessos.
No momento que acessamos pela sexta vez e ultrapassamos o limite autorizado, não conseguimos mais verificar os dados API, e recebemos a mensagem de pedido limitado, informando que o próximo pedido poderá ser feito daqui a 86 mil segundos, calculados de acordo com o prazo que colocamos.
HTTP 429 Too Many Requests
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Retry-After: 86389
Vary: Accept
{
"detail": "Pedido foi limitado. Expected available in 86389 seconds."
}
O teste de pessoa usuária logada está funcionando. Agora, verificaremos a pessoa usuária anônima.
Para verificar somente a situação de pessoas usuárias anônimas, voltaremos ao arquivo settings.py
e comentaremos os blocos DEFAULT_AUTHENTICATION_CLASSES
(de autenticação) e DEFAULT_PERMISSION_CLASSES
(de permissão).
REST_FRAMEWORK = {
#'DEFAULT_AUTHENTICATION_CLASSES': [
# 'rest_framework.authentication.BasicAuthentication',
# ],
#'DEFAULT_PERMISSION_CLASSES': [
# 'rest_framework.permissions.IsAuthenticated',
# ],
'DEFAULT_PAGINATION_CLASS': rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 20,
'DEFAULT_VERSIONING_CLASS': rest_framework.versioning.QueryParameterVersioning',
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '2/day',
'user': '5/day'
}
}
Acessaremos novamente essa API, mas com um navegador anônimo. No Chrome, basta pressionar "Ctrl+Shift+N" para abrir uma janela anônima, na qual colocaremos o endereço dessa API na rota /estudantes
.
Em seguida, carregaremos essa rota duas vezes, simulando dois acessos. Com apenas dois acessos, ele já mostra a mensagem de pedido limitado, informando o tempo que temos que esperar para a próxima requisição.
Por fim, voltando ao código, descomentaremos os blocos de autenticação e de permissão, e voltaremos os valores de throttling para os valores originais, 20 e 50.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_PAGINATION_CLASS': rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 20,
'DEFAULT_VERSIONING_CLASS': rest_framework.versioning.QueryParameterVersioning',
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '20/day',
'user': '50/day'
}
}
Com isso, conseguimos determinar globalmente a informação de limitar requisições. Podemos fechar o navegador.
Se verificarmos o cartão que estamos trabalhando no Trello, temos regras específicas para cada rota. Para a matrícula, devemos ter 50 requisições por dia para pessoas usuárias logadas, mantendo a mesma regra, contudo, devemos ter apenas 5 requisições por dia para pessoas usuárias anônimas.
A seguir, teremos que personalizar essa limitação por rota específica.
O curso Django REST Framework: trabalhando com permissões, documentação, limitações, CORS e deploy na AWS possui 110 minutos de vídeos, em um total de 48 atividades. Gostou? Conheça nossos outros cursos de Python em Programação, ou leia nossos artigos de Programação.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.