vendredi 17 juin 2016

Architecture of Flask REST API application - opinions and advices needed

Let me just say up front that I'm not looking for "the one right answer", but rather for opinions and experiences of the python developers out there who came across a similar issue. That is also why this question is a bit long :-).

I am developing a web REST API. The API is currently used only by javascript (ReactJS) based client, but is intended to serve as the backend for a number of mobile and desktop clients. It is nothing too complicated, but there is more logic than simple CRUD adapter on the database.

I normally use PHP for this sort of things, but I wanted to expand my knowledge so I decided to use Python, which I generally use for system scripts and small CLI apps. I also did some small web apps with Django in the past, but this framework didn't work for me, mainly because its ORM.

Right now I am struggling with an architecture for the API, which is, in fact, the whole subject of this question. I will try to describe how would I do it in PHP and how I have tried to implement this approach in Python (and how it didn't work).

So, the application is rather simple. There are multiple resources, its say categories, articles, and statistics (making stuff up to simplify my question), with GET,POST,PUT,DELETE methods to manage them. Categories and articles are simple and basically equals to their database counterparts. For statistics, there is some calculating done and the resulting JSON is not a representation of a single database entity, but rather a result to this calculation. Pretty standard app.

In PHP, I would simply do this: - define my database model as entities (using Doctrine ORM) - define DTO objects representing the resulting JSON and a mechanism to serialize them into json (I use JMS serializer from Symfony) - define a system container (usually done by framework) and services for manipulating entities and creating DTOs (this could also be separated into two layers, for the most purity, but I tend to do both of these things in the same services) - define controllers that take services from container, call them to get DTOs and serialize them to output

Therefore there would basically be three layers (above the database ones handled by doctrine, like mapper and DAO): - entity layer - definition of data model and database operations (Doctrine) - service layer - definition of data transformation, returning DTOs - presentation layer - responsible for delivering DTOs from services to caller and implementing REST

I have tried to implement this in Python (using Flask, SQLAlchemy and Marsmallow): - define my database model as entities (using SQLAlchemy) - define marsmallow schemas for serialization - define controllers for REST implementation and outputting serialized data

But here I got stuck. Defining DI container and services seems off to me in Python, because the whole import model of python basically takes care of that. So I just created service classes and imported them into controllers. But how would I go about transforming data to JSON in a cleanest possible way? I don't want to feed database entities to marsmallow schemas directly, because this would only work for object that are represented directly (categories, articles), but not for statistics. I don't want to use only dictionaries for transporting data between entities and schemas, because I want to be as strict as possible, which means using clearly defined objects. I could use DTO objects in addition to schemas, but that way I would be duplicating information for no obvious reason.

What is your take on this? How would you implement this in the cleanest and most pythonic way?

Thanks in advance for all suggestions!

Aucun commentaire:

Enregistrer un commentaire