Todo (the irony):
- Actually make a slideshow.
- Create code examples (keep it simple, a todo for example).
- Simple SQLAlchemy todo example.
- Not auth or users.
- Practice giving the presentation to folks.
Overview
All allow for class based API design and varying degrees of control over endpoints.
- Classy allows the most granular control and is designed specifically to be an extension to Flask.views.MethodView and Flask.view.View rather than strictly an API tool.
- Restful allows for a less fine tuned experience than Classy but is designed specifically with designing APIs in mind.
- Restless allows the least amount of control over the API and is heavy handed in it's configuration.
Classy
- pip install flask-classy
- Docs are located at http://pythonhosted.org/Flask-Classy/
- Views are defined like: ExampleView(FlaskView) -> localhost:5000/example/
- Has magic routes: get, post, put, delete, patch, etc.
- Will return a 405 Method Not Allowed if a HTTP verb isn't defined.
- Extra arguments are also automatically pulled from the URL:
def get(self, id)
pass
/example/<arg1>/<arg2>/ - However, extra arguments aren't explicitly typed
- Can also define custom routes: simply define a new method, def custom(self): pass -> localhost:5000/example/custom
- Endpoints: url_for('Example:custom')
- Allows for custom routes with the route decorator (located in flask.ext.classy)
@route('/notcustom/')
def custom(self):
pass - Route decorator can also define custom endpoints and do all things that the regular Flask.route decorator can.
- Including explicitly typing arguments: @route('/<int:id>/)
- Stacking route decorators doesn't cause collisions, rather Classy resolves them by adding identifiers.
- Want a custom endpoint? Sure thing, brah. @route(endpoint='bro'). Classy also passes these straight to Flask. url_for('bro') instead of url_for('Example:bro')
- Classy also allows changing the route base and route prefix. Add either route_base or route_prefix as a class variable to the view. OR when you're registering it, add the route_prefix or route_base keyword option.
- Pre and post processors? Got those, too. before_request and after_request run before all requests. Care about only certain routes? before_custom and after_custom.
- Order of resolution: @app.before_request, ExampleView.before_request, before_custom, custom, after_custom, ExampleView.after_request, @app.after_request
- Tired of decoratoring a bunch of routes by hand? Gotcha back. Either decorate by hand OR define decorator as a list of decorators.
- Need a subdomain? Done. You guessed it: subdomain class variable or when registering use the subdomain keyword.
- Flask-Classy is not tied to a specific mimetype or data model -- use it to return XML from Mongo or SOAP from SQLAlchemy, render a template from a cache or send raw files that your cat typed when she jumped on your keyboard.
- Makes it great for building on Blueprints OR building APIs.
- Suggested companion libraries: Marshmallow (data marshalling) and mimerender (render different output for different mimetypes), WTForms (data validation).
- Cons: Currently no error handling. Register FlaskView on a Blueprint to handle errors.
Flask-Restful
- Developed by Twilio for their API (which is a fun service capable of cool things).
- Designed specifically with APIs in mind.
- Comes with native JSON support, but allows you to support other mimetypes by defining a data processor -- support XML, SOAP, CSV, plain text.
- Methods should return a dictionary.
- Comes with a request parser (built like argparse or optparse) (located at flask.ext.restful.reqparse.RequestParser) AND marshalling (that allows for nested and custom fields, feels like Marshmallow) located at flask.ext.restful.marshal_with and flask.ext.restful.fields
- API resources are derived from flask.ext.restful.Resource and the API manager is located at flask.ext.restful.Api.
- Allows wrapping of all resources with the method_decorators class variable.
- Doesn't allow custom routes (i.e. adding /example/custom/) and requires explicit definition of variables upon registration.
- However, it does allow one Resource to manage multiple URI endpoints.
- More on RequestParser, marshals_with and fields here.
Flask-Restless
- Explicitly bound not only to SQLAlchemy but also to JSON -- input AND output.
- Almost completely configuration based.
- Where Classy has FlaskView and Restful has Resource, Flask-Restless lies directly atop your models.
- Other restrictions: models must have an id field that's the primary key AND is an integer (though, that's almost the default) AND the model must have an __init__ method that accepts all fields (SQLAlchemy does that by default, though). Supports BOTH flask-sqlalchemy AND vanilla SQLAlchemy.
- You define which methods are allowed on a resource like a regular Flask route: ['GET', 'POST'] -- a list of verbs.
- A note on verbs: PUT is aliased to PATCH. I disagree with this because PUT is to create or modify an entire resource at the endpoint (think UPSERT in SQL) and PATCH is a partial modification of a resource at an endpoint. Semantics, but semantics are important.
- Good news: API-Model bridges are registered automatically (though, you can also return them for inspection).
- Has a built in search feature.
- Customization is painful. You must specify individual wrappers and processors for EACH verb.
- Other cons: No built in validation. Documentation suggests validation in the models.
- Project layout ends up with fat, fat models and almost non-existent controllers.