Custom Data Layer in Open Event API Server
Open Event API Server uses flask-rest-jsonapi module to implement JSON API. This module provides a good logical abstraction in the data layer.
The data layer is a CRUD interface between resource manager and data. It is a very flexible system to use any ORM or data storage. The default layer you get in flask-rest-jsonapi is the SQLAlchemy ORM Layer and API Server makes use of default alchemy layer almost everywhere except the case where I worked on email verification part.
To add support for adding user’s email verification in API Server, there was need to create an endpoint for POST /v1/users/<int:user_id>/verify
Clearly here we are working on a single resource i.e, specific user record. This requires us to use ResourceDetail and the only issue was there is no any POST method or view in ResourceDetail class. To solve this I created a custom data layer which enables me to redefine all methods and views by inheriting abstract class. A custom data layer must inherit from flask_rest_jsonapi.data_layers.base.Base.
Creating Custom Layer
To solve email verification process, a custom layer was created at app/api/data_layers/VerifyUserLayer.py
def create_object(self, data, view_kwargs): user = safe_query(self, User, 'id', view_kwargs['user_id'], 'user_id') s = get_serializer() try: data = s.loads(data['token']) except Exception: raise UnprocessableEntity({'source': 'token'}, "Invalid Token") if user.email == data[0]: user.is_verified = True save_to_db(user) return user else: raise UnprocessableEntity({'source': 'token'}, "Invalid Token")
Using custom layer in API
We can easily provide custom layer in API Resource using one of the properties of the Resource Class
data_layer = { 'class': VerifyUserLayer, 'session': db.session }
This is all we have to provide in the custom layer, now all CRUD method will be directed to our custom data layer.
Solution to our issue
Setting up custom layer provides us the ability to create our custom resource methods, i.e, modifying the view for POST request and allowing us to verify the registered users in API Server.
On Setting up the data layer all I need to do is create a ResourceList with using this layer and with permissions
class VerifyUser(ResourceList): methods = ['POST', ] decorators = (jwt_required,) schema = VerifyUserSchema data_layer = { 'class': VerifyUserLayer, 'session': db.session }
This enables me to use the custom layer, VerifyUserLayer for ResourceList resource.
Resources
- Flask-rest-jsonapi Data layer
http://flask-rest-jsonapi.readthedocs.io/en/latest/data_layer.html - JSON-API Spec
http://jsonapi.org/format/