In thefirst part of this three-part tutorial series, we saw how to write RESTful APIs all by ourselves using Flask as the web framework. The previous approach provided a whole lot of flexibility but also included writing a lot of code that otherwise could have been avoided in more generic cases.
In this part, we will use a Flask extension, Flask-Restless , which simply generates RESTful APIs for database models defined with SQLAlchemy. I will take the same sample application as in the last part of this series to maintain context and continuity.
Installing DependenciesWhile continuing with the application from the first part, we need to install only one dependency:
$ pip install Flask-Restless The ApplicationFlask-Restless makes addingRESTful API interfaces to models written with SQLAlchemy a piece of cake.First, add the REST APIManager from the flask.ext.restless extension to the application configuration file.
flask_app/my_app/__init__.py
from flask.ext.restless import APIManagermanager = APIManager(app, flask_sqlalchemy_db=db)
Just adding the above couple of lines to the existing code should suffice.
flask_app/my_app/catalog/views.py
This file comprisesthe bulk of the changes from the previous part. Below is the complete rewritten file.
from flask import Blueprintfrom my_app import manager
from my_app.catalog.models import Product
catalog = Blueprint('catalog', __name__)
@catalog.route('/')
@catalog.route('/home')
def home():
return "Welcome to the Catalog Home."
manager.create_api(Product, methods=['GET', 'POST'])
It is pretty self-explanatory how the above code would work. We just imported the manager that was created in aprevious file, and it is used to create an API for the Product model with the listed methods . We can add more methods like DELETE , PUT , PATCH , etc. as needed.
Application in ActionLet's test this application by creating some products and listing them. The endpoint created by this extension by default is http://localhost:5000/api/product .
As I did in the last part of this tutorial series, I will test this using the requests library via terminal.
>>> import requests>>> import json
>>> res = requests.get('http://127.0.0.1:5000/api/product')
>>> res.json()
{u'total_pages': 0, u'objects': [], u'num_results': 0, u'page': 1}
>>> d = {'name': u'iPhone', 'price': 549.00}
>>> res = requests.post('http://127.0.0.1:5000/api/product', data=json.dumps(d), headers={'Content-Type': 'application/json'})
>>> res.json()
{u'price': 549.0, u'id': 1, u'name': u'iPhone'}
>>> d = {'name': u'iPad', 'price': 649.00}
>>> res = requests.post('http://127.0.0.1:5000/api/product', data=json.dumps(d), headers={'Content-Type': 'application/json'})
>>> res.json()
{u'price': 649.0, u'id': 2, u'name': u'iPad'}
>>> res = requests.get('http://127.0.0.1:5000/api/product')
>>> res.json()
{u'total_pages': 1, u'objects': [{u'price': 549.0, u'id': 1, u'name': u'iPhone'}, {u'price': 649.0, u'id': 2, u'name': u'iPad'}], u'num_results': 2, u'page': 1} How to Customize
It is really handy to have the RESTful APIs created automatically, but each application has some business logic which calls for customizations, validations, and clever/securehandling of requests as needed.
Here, request preprocessors and postprocessors come to the rescue.As the names signify, methods designated aspreprocessors run before the processing of therequest, andmethods designated aspostprocessors run after the processing of the request. create_api() is the place where they are definedas dictionaries of the request type ( GET , POST , etc.) and themethods as listwhich willact as preprocessors or postprocessors on the specified request. Below is a template example:
manager.create_api(Product,
methods=['GET', 'POST', 'DELETE'],
preprocessors={
'GET_SINGLE': ['a_preprocessor_for_single_get'],
'GET_MANY': ['another_preprocessor_for_many_get'],
'POST': ['a_preprocessor_for_post']
},
postprocessors={
'DELETE': ['a_postprocessor_for_delete']
}
)
The GET , PUT , and PATCH requests have the flexibility of beingfired for single as well asmultiple records; therefore, they have two types each. In the code above, notice GET_SINGLE and GET_MANY for GET requests.
The preprocessors and postprocessors accept different parametersfor each type of requestand work without any return value. This is left for you to try on your own.
ConclusionIn this part of this tutorial series, we saw how to create a RESTful API using Flaskjust by adding a couple of lines to a SQLAlchemy-based model.
In the next and lastpart of this series, I will cover how to create a RESTful API using another popular Flask extension, but this time, the API will be independent of the modeling tool used for thedatabase.