Flask RESTplus

Desenvolvendo a sua API e ganhando documentação de presente.

Evandro F. Souza
Training Center
6 min readAug 23, 2018

--

Na empresa no qual trabalho, iniciamos um novo projeto, o sistema que iremos desenvolver será uma API.

Ao iniciar um projeto novo, é sempre bom tomar certos cuidados, alguns são comuns para qualquer software que for desenvolver, por exemplo: organização do código fonte , cobertura de testes, configurações em variáveis de ambiente, CI\CD, etc. Quando desenvolvemos uma API, existe um cuidado específico, que é manter a documentação atualizada para quem a consumirá.

Manter uma documentação atualizada com o código fonte pode ser um problema. Pois, assim como os comentários de código, conforme o sistema evolui, a documentação pode não evoluir em conjunto e ficar obsoleta. Uma das soluções para garantir que a evolução em conjunto aconteça, é utilizar um framework que gere ela com base no código fonte. O objetivo deste post apresentar o Flask RESTplus, um framework para Python que possui esta facilidade.

Se quiser mais detalhes sobre os pontos de atenção na construção do seu software. Neste post é explicado sobre o Twelve Factor app, um manifesto de boas práticas para microservices (na minha opinião, ele serve para qualquer tipo de sistema).

O que é o Flask?

Flask é um micro-framework web escrito em Python. Como é um micro-framework, o Flask por si só possui poucas funcionalidades. A abordagem dele é diferente da de um framework como o Django, que é conhecido por incluir diversas funcionalidades. O Flask não vem com ORM, serializers, gerenciamento de usuário ou suporte a internacionalização. Contudo, todas essas funcionalidades e muitas outras estão disponíveis em extensões, tornando Flask um ecossistema rico e desacoplado.

Acredito que o principal desafio para um desenvolvedor Flask novato é escolher as extensões certas e combiná-las para obter o conjunto correto de funcionalidades.

O que é o Flask RESTplus?

Flask-RESTplus é uma extensão do Flask que visa tornar o desenvolvimento de APIs REST fácil e rápido. Ele fornece facilidades sintáticas que tornam o código de fácil leitura e manutenção. Dentre muitas funcionalidades, na minha opinião, a que mais se destaca é a capacidade de gerar uma documentação interativa para sua API utilizando o Swagger UI.

O que é o Swagger UI?

A Swagger UI faz parte de um conjunto de tecnologias para documentar APIs RESTful. O Swagger evoluiu para a especificação OpenAPI, atualmente com curadoria da Linux Foundation.

Uma vez que você tenha uma especificação OpenAPI você pode usar ferramentas para gerar documentação ou até mesmo código(cliente ou servidor) em várias linguagens. Dê uma olhada no swagger.io para mais informações.

A Swagger UI é uma ótima ferramenta para descrever e visualizar APIs. Ela gera uma página web, que documenta sua API e permite que você faça consultas de teste. Clique aqui para ver uma demonstração.

Vamos ver o código

Para estudar este framework, criei uma pequena aplicação de exemplo. Vamos iniciar baixando este código e executando a demonstração na nossa máquina, a partir dai, vamos analisar a implementação.

Preparando o ambiente

Para executar este projeto, utilizei o sistema operacional Ubuntu 18 e rodei tudo dentro de um virtual environment de Python.

  1. Instale Python 3, pip e Virtualenv.
sudo apt-get install python3-pip python3-dev python-virtualenv

2. Crie e ative o Virtualenv.

virtualenv --system-site-packages -p python3 .env3
source .env3/bin/activate

3. Clone o repositório:

cd /minha/pasta/de/projetos/
git clone https://github.com/evandroferreiras/studies_diary_api
cd studies_diary_api

4. Instale as extensões:

pip install -r requirements.txt

5. Rode a API:

PYTHONPATH=./ FLASK_ENV=development  python ./studies_diary/app.py

Após isso, acesse a URL http://127.0.0.1:5000/, você deverá ver algo como na imagem abaixo:

Figura 1 —Swagger UI da API de demonstração

A estrutura de pastas

Quando o assunto é estrutura de pastas, organização de arquivos e etc. Não existe uma regra bem estabelecida, o importante é organizar de uma maneira que faça sentido para a equipe. Abaixo compartilho a maneira que organizei este código — me inspirei bastante neste belo exemplo.

Definindo a aplicação

Por padrão, a inicialização das aplicações Flask sempre ficam no arquivo app.py. Vamos analisar abaixo:

app.config: O Flask RESTplus possui muitas variáveis de configuração. Ao habilitar o RESTPLUS_VALIDATE, haverá um comportamento de validação dos campos esperados em cada requisição. Já o ERROR_404_HELP desabilita uma mensagem de erro padrão, que tenta adivinhar a URL sempre que o usuário digita algo errado.

blueprint: O Flask Blueprint é um conceito utilizado para “componentizar” as aplicações. É como se fosse a “planta” de sua API. Com a “planta” em mãos, vocês pode “construir” várias casas (ou APIs) iguais. O Blueprint é uma prática simples de ser adotada e que auxilia no suporte do crescimento de sua aplicação.

Namespace: O RESTPlus utiliza o conceito de Resources e Namespaces. Um Resource é basicamente a representação de algum endpoint da sua API. E um Namespace é um conjunto de Resources. No nosso exemplo, ambos são definidos no diretório /studies_diary/endpoints. Para que a API reconheça a existência destes Namespaces, é necessário adiciona-los utilizando a função api.add_Namespace()

Namespaces e Resources

O RESTPlus já possui um Namespace padrão, observando na Figura 1 é possível notar que já existe um endpoint chamado /hello na nossa API e ele está dentro do Namespace default. Nada impede de adicionar todos os Resources no Namespace default, contudo, a possibilidade de múltiplos Namespaces torna o código mais organizado, sendo possível criar um por arquivo e também definir uma documentação mais detalhada, agrupadas por responsabilidades e assim por diante.

Vamos visualizar abaixo como são definidos endpoints e Resources:

Na variável ns_category, utilizando a função api.Namespace, está sendo definido o Namespace para o endpoint /category. Note que esta mesma variável é utilizada como decorator de ambas classes. Este decorator é utilizado para definir qual é a URL do endpoint. No exemplo anterior estamos definindo dois endpoints:

  • /category — GET/POST decorator: @ns_category.route('/')
  • /category/1 — GET decorator: @ns_category.route('/<int:id>')

As classes CategoryItem e CategoryCollection herdam da classe Resource. Cada Resource é uma classe que contêm funções que serão mapeadas em métodos HTTP. Ou seja, para implementar um método HTTP put é necessário implementar uma função com o mesmo nome. As seguintes funções são mapeadas: get,post,put,delete,path,options e head.

É possível também utilizar o decorator @api.response() para documentar quais códigos de status HTTP cada método deve retornar e o que significa cada um deles. No exemplo anterior é possível observar o uso deste decorator para documentar o significado do status 404.

Após tudo configurado, observe como fica bem documentado no Swagger UI:

Figura 2 — Swagger UI mostrando detalhes do Namespace e Resources

Ao clicar no botão “Try it out!” a requisição será enviada e a resposta mostrada na tela. É muito útil!

Documentando e validando parâmetros

O RESTPlus permite validar e documentar automaticamente o formato dos objetos JSON recebidos usando API models.

Uma API model define o formato do objeto listando os campos esperados. Cada campo deve ter um tipo associado (string,integer,datetime), o que determinará qual valor é considerado válido.

Na nossa API, os models estão localizados no diretório /serializers/. Abaixo é possível visualizar um exemplo de API model:

Após o model definido, é possível aplicar ele a um método utilizando os decorators @api.expect() e @api.marshal_with().

@api.expect(category_serializer)
@api.marshal_with(category_serializer, code=201)
def post(self):
return self.bus.add(api.payload['title'])

No exemplo anterior, o expect é utilizado para documentar e validar o formato de entrada deste método post . Já o marshal_with é utilizado para documentar o formato de retorno do método post.

Como no model o campo id está definido como read only, o método post vai esperar somente pelo campo title , contudo, após inserido o valor, ele vai retornar o title junto com oid gerado.

Conclusão

O Flask é um ótimo micro-framework, ele realmente é extensível e customizável. Isso é interessante, assim você pode construir sua aplicação sob-medida (evitando utilizar um canhão para matar uma mosca). Contudo, é interessante levar alguns pontos em consideração quando for escolher a sua extensão.

Quando estávamos decidindo sobre quais extensões utilizar, sabíamos que uma das necessidades era ser algo para gerar a documentação automaticamente. Durante as pequisas apareceram várias opções além da RESTPlus. A primeira vista todas pareciam boas candidatas, mas quando começamos a olhar mais afundo, percebemos que algumas estavam anos sem um commit e com várias issues abertas no GitHub. Outras possuíam pouca aderência da comunidade (poucas estrelas no repositório do GitHub, poucas perguntas e respostas no StackOverFlow, etc).

Na verdade, em minha opinião, essa simples análise é válida para qualquer ferramenta open source que você for adotar. Isso evita tornar-se um refém solitário de uma ferramenta abandonada.

Quero aprender mais sobre Flask e VueJS, vou aproveitar essa oportunidade e criar um sistema para auxiliar na organização dos meus estudos (que expliquei neste post). Então esperem por mais post sobre estes assuntos 😊.

Se quiser trocar uma ideia ou entrar em contato comigo, pode me achar no Twitter(@e_ferreirasouza) ou Linkedin.

Grande abraço e até a próxima!

--

--