mts-ai / FastAPI-JSONAPI

JSON:API for FastAPI
https://mts-ai.github.io/FastAPI-JSONAPI/
MIT License
109 stars 10 forks source link

Layers of the framework #92

Open RandyRomero opened 4 months ago

RandyRomero commented 4 months ago

Thank you for you great framework, guys :)

The following is more like a feature request

While I was trying to switch our webapp at work from the dead starlette-jsonapi to your new and shiny FastAPI-JSONAPI, I understood I really miss one important thing (at least for me).

I noticed that in FastAPI-JSONAPI there is an HTTP-layer (view classes) and a persistence-layer (e.g. SqlalchemyDataLayer), but there is no a dedicated logic layer. Of cource, one can redefine methods of view classes or embed theirs business logic in SqlalchemyDataLayer methods, but it all would lead to a high coupling between the business logic and the FastAPI-JSONAPI framework.

So, I think it would be great if view classes triggered not the data layer right away, but methods of a dedicated logic class. Something like this:

class SqlalchemyDataLayer(...):
    ...
    async get_one_object(entity_Id, **kwargs):
        ....

class LogicLayer(...):
    ....
    async get_one_object(self, entity_id, data_layer,  **kwargs):

        # does whatever business logic requires
        # like sending an event somewhere, do some calculations, check some business rules, calls other microservices or any external APIs etc
        db_entity = await data_layer.get_object(entity_id)
        # converts ORM object to pydantic model, also provides a method that allow to customize this convertion
        # does whatever business logic requires
        return entity

class DetailViewBase(ViewBase):
    ...
    async def handle_get_resource_detail(...):
        # does some HTTP stuff, like validation, deserialization
        obj = await self.logic_layer.get_one_object(obj_id, data_layer)
        # the rest of the HTTP stuff

I did something like this in our webapp at work, but in order to do that I had to redefine a lot of FastAPI-JSONAPI internals, which, of course, can lead me to a lot of compatibility problems each time you update the framework So it would be nice to have it out-of-the box if possible.

It's not like I anticipate you'll do it, because that's quite a lot of work and will definitely break the compatibility with the older versions, but if you would one day, it would be awesome