In REST We Trust¶
CCEP |
4 |
Title |
In REST We Trust |
Version |
1 |
Author |
Markus Holtermann |
Date |
2019-04-01 |
Status |
Accepted |
Introduction¶
A couple of weeks ago it was decided that cloud-app is to be providing a RESTful API instead of GraphQL in the future. This CCEP discusses some of the pros and cons of six different Flask REST frameworks and concludes with a recommendation on which one to use.
Discussion¶
The key focus on the discussion of the following six REST frameworks or REST implementations lies on their ease of input validation as well as the weight and complexity of the whole framework/stack.
The frameworks this CCEP looks at are:
Pure Flask + jsonschema
flask-expects-json¶
Number 1 (flask-expects-json) seems nice but isn’t a viable option from a business perspective. The library has a single maintainer with the latest changes being more than one year ago. There’s too much at stake to put money on that solution.
Flask-RESTful and Flask-RESTPlus¶
Numbers 2 (Flask-RESTful) and 3 (Flask-RESTPlus) seem to solve all the problems that could ever come up in the CrateDB Cloud back-end stack. But to solve all the problems, both frameworks provide a rather high level of abstraction. They seem rather complex and elaborate for the tasks that need to be accomplished.
With the experience and lessons learned from GraphQL, the choice should fall on a simple, yet not constraining framework. Neither Flask-RESTful nor Flask-RESTPlus fulfills that requirement.
flask-rest-api and flask-marshmallow¶
Numbers 4 (flask-rest-api) and 5 (flask-marshmallow) rely on a (de)serialization library called marshmallow. This library provides an interface for input validation. While flask-rest-api works with class-based views, there doesn’t appear to be much value for them at the current time. flask-marshmallow doesn’t limit which view style can be used.
From a technical perspective, using the marshmallow library directly would be suitable as well, although the documentation says:
[flask-marshmallow] adds additional features to marshmallow, including URL and Hyperlinks fields for HATEOAS-ready APIs.
Flask with jsonschema¶
Number 6 (Flask with jsonschema) provides input value validation solely, everything else remains a task of the Flask application. But input validation and input deserialization go beyond being able to check that something follows a JSON schema. Validating that the referred to UUID exists or deserializing the object behind a UUID are utilities and niceties that come in handy and need to be repeated otherwise.
Proposal¶
At this point, the recommendation is to go with flask-marshmallow.
Basing the validation off of marshmallow allows for a nice, auto-generated OpenAPI Spec using apispec. JSON Schema and OpenAPI are not 100% compatible as per the swagger.io docs. Thus, basing the API off of JSON Schema when thoughts are floating around to provide a Swagger/OpenAPI documentation, does not seem right.
Impact¶
The decision made herein is indicatory. While the API design is mostly unrelated to which library is chosen, using one over the other may or may not make switching easier.
Choosing the “wrong” library will, in the worst case, require a rewrite of the validation, serialization and deserialization integration. The complexity and most logic is wrapped in views and controllers, making the library chose here rather loosely coupled.