Advertisement
  1. Code
  2. Flask

Construindo APIs RESTful Com Flask: Abordagem Faça-Você-Mesmo

Scroll to top
Read Time: 6 min
This post is part of a series called Building RESTful APIs With Flask.
Building RESTful APIs With Flask: An ORM With SQLAlchemy

() translation by (you can also view the original English article)

Representational State Transfer (REST) é um estilo de projeto de arquitetura de desenvolvimento web que se refere à separação lógica dos recursos da API, habilitando fácil acesso, manipulação e dimensionamento. Componentes reusáveis são escritos para sere facilmente adminitrados através de requisições HTTP simples e intuitivas, como GET, POST, PUT, PATCH e DELETE (pode ter mais, mas essas são as mais usadas).

Apesa da aparência, REST não exige um protocolo ou padrão. Apenas prepara um estilo arquitetural de software para a escrita de aplicações web e APIs, resultando na simplificação de interfaces dentro e fora da aplicação. APIs de serviços web escritas seguindo os princípios REST são chamadas de APIs RESTful.

Nessa série de três partes, cobriremos maneiras diferentes que APIs RESTful podem ser criadas usando Flask, uma framework web. Nessa primeira parte, cobriremos como criar APIs REST baseadas em classes, na mão, ou seja, implementando sem uso de extensões de terceiros. Nas outras partes da série, cobriremos como lançar mão de várias extensões do Flask para construir APIs REST mais efetivas e de forma mais fácil.

Assumimos que tenha entendimento básico do Flask e boas práticas de configuração de ambientes usando virtualenv, que devem ser seguidas ao desenvolver aplicações em Python.

Instalando Dependências

Os pacotes a seguir precisam ser instalados para a aplicação que desenvolveremos.

1
$ pip install flask
2
$ pip install flask-sqlalchemy

Os comando acima deveriam instalar todos os pacotes requeridos para a aplicação funcionar.

A Aplicação Flask

Para esse tutorial, criaremos uma pequena aplicação onde teremos um modelo Product trivial. E demonstraremos como escrever uma API Restful para o mesmo. Abaixo temos a estrutura da aplicação.

1
flask_app/
2
    my_app/
3
        - __init__.py
4
        product/
5
            - __init__.py      // Empty file
6
            - models.py
7
            - views.py
8
    - run.py

Não criaremos front-end para essa aplicação já que os pontos de acesso das APIs RESTful podem ser testadas diretamente com chamadas HTTP usando vários outros métodos.

flask_app/my_app/__init__.py

1
from flask import Flask
2
from flask.ext.sqlalchemy import SQLAlchemy
3
4
app = Flask(__name__)
5
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
6
db = SQLAlchemy(app)
7
8
from my_app.catalog.views import catalog
9
app.register_blueprint(catalog)
10
11
db.create_all()

No arquivo acima, a aplicação foi configurada com a inicialização das extensões e a criação da base de dados. A última declaração cria uma nova base de dados no local provido por SQLALCHEMY_DATABASE_URI se uma base de dados ainda não existir no local, caso contrário, carrega a aplicação com a base existente.

flask_app/my_app/catalog/models.py

1
from my_app import db
2
3
class Product(db.Model):
4
    id = db.Column(db.Integer, primary_key=True)
5
    name = db.Column(db.String(255))
6
    price = db.Column(db.Float(asdecimal=True))
7
8
    def __init__(self, name, price):
9
        self.name = name
10
        self.price = price
11
12
    def __repr__(self):
13
        return '<Product %d>' % self.id

No arquivo acima, criamos um modelo bem trivial para salvar o nome e preço de um Product (produto). Isso criará uma tabela no SQLite correspondendo ao detalhes providos no modelo.

flask_app/my_app/catalog/views.py

1
import json
2
from flask import request, jsonify, Blueprint, abort
3
from flask.views import MethodView
4
from my_app import db, app
5
from my_app.catalog.models import Product
6
7
catalog = Blueprint('catalog', __name__)
8
9
@catalog.route('/')
10
@catalog.route('/home')
11
def home():
12
    return "Welcome to the Catalog Home."
13
14
15
class ProductView(MethodView):
16
17
    def get(self, id=None, page=1):
18
        if not id:
19
            products = Product.query.paginate(page, 10).items
20
            res = {}
21
            for product in products:
22
                res[product.id] = {
23
                    'name': product.name,
24
                    'price': str(product.price),
25
                }
26
        else:
27
            product = Product.query.filter_by(id=id).first()
28
            if not product:
29
                abort(404)
30
            res = {
31
                'name': product.name,
32
                'price': str(product.price),
33
            }
34
        return jsonify(res)
35
36
    def post(self):
37
        name = request.form.get('name')
38
        price = request.form.get('price')
39
        product = Product(name, price)
40
        db.session.add(product)
41
        db.session.commit()
42
        return jsonify({product.id: {
43
            'name': product.name,
44
            'price': str(product.price),
45
        }})
46
47
    def put(self, id):
48
        # Update the record for the provided id

49
        # with the details provided.

50
        return
51
52
    def delete(self, id):
53
        # Delete the record for the provided id.

54
        return
55
56
57
product_view =  ProductView.as_view('product_view')
58
app.add_url_rule(
59
    '/product/', view_func=product_view, methods=['GET', 'POST']
60
)
61
app.add_url_rule(
62
    '/product/<int:id>', view_func=product_view, methods=['GET']
63
)

O grande problema desse tutorial é lidar com o arquivo acima. Flask provê um utilitário chamado visões conectáveis que nos permitem criar visões na forma de classes ao invés de funções. Despache baseado em métodos (MethodView) é uma implementação de visão conectável que permite escrever métodos correspondentes aos métodos HTTP. No exemplo acima, escrevemos métodos get() e post() correspondendo aos métodos HTTP GET e POST.

Rotas também são implementadas diferentemente, ao final do arquivo acima. Podemos especificar métodos que suportaremos para qualquer regra em particular. Qualquer outra chamada HTTP encontrará Error 405 Method not allowed.

Executando a Aplicação

Para executar a aplicação, execute o script run.py. O conteúdo do script é:

1
from my_app import app
2
app.run(debug=True)

Agora execute-o na linha de comando:

1
$ python run.py

Para verificar se a aplicação funciona, digite http://127.0.0.1:5000/ no navegador e uma tela simples de bem vindo deveria aparecer.

Testando a API RESTful

Para testar a API, realizaremos chamadas HTTP usando quaisquer métodos disponíveis. As GET podem ser feitas diretamente pelo navegador. As POST podem ser feitas com uma extensão para Chrome, Postman, ou pela linha de comando com curl, ou podemos usar a biblioteca requests do Python. Usaremos a biblioteca requests para efeitos de demonstração.

Façamos as GET primeiro para garantir que ainda não temos produtos criados. Pelo padrão de APIs RESTful, uma chamada parecida com /product/ deveria listar todos os produtos. Depois, criaremos alguns produtos via POST em /product/ com alguns dados. Então um GET para /product/ deveria listar todos os produtos criados. Para obter um produto em específico, um GET para /product/<id do produto> deveria funcionar. Abaixo, temos um exemplo das chamadas que podem ser feitas usando o exemplo.

1
$ pip install requests
2
$ python
3
>>> import requests
4
>>> r = requests.get('http://localhost:5000/product/')
5
>>> r.json()
6
{}
7
>>> r = requests.post('http://localhost:5000/product/', data={'name': 'iPhone 6s', 'price': 699})
8
>>> r.json()
9
{u'1': {u'price': u'699.0000000000', u'name': u'iPhone 6s'}}
10
>>> r = requests.post('http://localhost:5000/product/', data={'name': 'iPad Pro', 'price': 999})
11
>>> r.json()
12
{u'2': {u'price': u'999.0000000000', u'name': u'iPad Pro'}}
13
>>> r = requests.get('http://localhost:5000/product/')
14
>>> r.json()
15
{u'1': {u'price': u'699.0000000000', u'name': u'iPhone 6s'}, u'2': {u'price': u'999.0000000000', u'name': u'iPad Pro'}}
16
>>> r = requests.get('http://localhost:5000/product/1')
17
>>> r.json()
18
{u'price': u'699.0000000000', u'name': u'iPhone 6s'}

Conclusão

Nesse tutorial, vimos como criar interfaces RESTful para nós mesmo usando o utilitário de visões conectáveis do Flask. Essa é a abordagem mais flexível ao criar APIs REST mas requer muito código a ser escrito.

Existem extensões que tornam a vida mais simples e automatizam bastante a implementação de APIs RESTful. Cobriremos elas nas próxima partes dessa série.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.