5 ms·
It's always a bit risky to document contracts with the left hand and implement them with the right. The best case to me is a framework that serves both function
by jbmsf 7y ago
It's always a bit risky to document contracts with the left hand and implement them with the right. The best case to me is a framework that serves both functions at once.
I built something like this at my last job by having an opinionated layer on top of Flask in Python. The idea was to have a small set of standard operation types (think:create, retrieve, update) and choices as to input/output types (via the marshmallow library ) and the function to process the route. This turns out to be enough to generate both the api contract and the boilerplate for routing, (un)marshalling, etc.
You can find the implementation in this repo: https://github.com/globality-corp/microcosm-flask https://github.com/globality-corp/microcosm-flask
- BerislavLopac 7y agoYes, FastAPI [0] takes a similar approach. The problem here is that the single-source-of-truth for your contract is not OpenAPI, but rather your Flask implementation, with the OpenAPI being a documentation artefact; this is problematic for two reasons: 1. Just like any other documentation, it is difficult to verify that the documentation is actually correct and does not diverge from he underlying implementation. This is a lesser issue, as it can be mitigated with good integration testing practices. 2. The bigger issue, for me, is that any clients depends on the service implementation. In practice, it is very common to build clients -- especially complex ones like React or mobile UI -- alongside the service development, and if the spec is defined first both can be done in parallel. With the above approach you either need to a) wait for the service implementation to be complete before you can start implementing the client, or b) base the client on an OpenAPI spec which might potentially differ from the one your framework will generate based on the implementation. I have recently worked on a project which had that same issue, and our initial solution was to build tests which would compare the generated OpenAPI with the design specification, but that turned to be extremely complex when we started running into all of the edge cases. The alternative was to treat OpenAPI as the single-source-of-truth, using it to generate routes and execute validation over requests and responses. The first attempt used Connexion [1], which proved to be a bit too incomplete for our needs, so we implemented an alternative framework [2] (which includes a basic client-side support as well). [0] https://fastapi.tiangolo.com/ https://fastapi.tiangolo.com/ [1] https://connexion.readthedocs.io https://connexion.readthedocs.io [2] https://github.com/berislavlopac/pyotr https://github.com/berislavlopac/pyotr (still under heavy construction)
- jbmsf 7y agoThere's a lot to unpack here, but I'll focus on #2, specifically the client dependency. My approach is to assign projects to teams with members who can work on both the client and server layers so that the question is less of client blocking on server and more of client and server working together. In addition, I like an "API first" approach, which in this case means building the signature of the API functions (e.g with mock data) before finishing the implementation. That is: client is still blocked on server to define the API, but they are not blocked on implementing the API and client works closely enough with server (or is able to do both) such that they aren't blocked on the definition. As always, many software problems devolve into people problems once you stare at them hard enough.
- Rotareti 7y ago> ... and if the spec is defined first both can be done in parallel. You could simply write the complete interface down in Python/FastAPI without actual implementation and generate the OpenAPI spec from that interface. That way both teams could start soon.
- BerislavLopac 7y agoOh most definitely, there is a bunch of ways to solve this concrete problem. But none of them addresses the conceptual issue of the specification authority.