Connecting API's and front-end applications through OpenAPI auto generation
Communication between an API and client-side applications has posed several challenges. The back-end (BE) developers might break backwards compatibility or forget to correctly specify required and optional fields. These are some examples of human oversight that we have encountered in the past. They lead to unforeseen errors and are difficult to identify. There are already known solutions like automated endpoint documentation through a web UI like Swagger UI or Scalar as well as schema based approaches like the GraphQL Schema. The web UI’s don’t enforce anything and the GraphQL implementations did not offer us the promised advantages. We looked further into alternatives to streamline consistency between FE and BE.
Automatic endpoint documentation
For model-view-controller (MVC) applications in which the data structures passed from and to a BE application are very explicit, documentation can already be auto-generated. This is a very common practice that is a base functionality of many modern day REST frameworks (express, nestJS, …). The auto-generation and rendering relies on a well known specification called OpenAPI. An example of an auto-generated endpoint documentation can be seen in image 1. Another great example of what API documentation of REST endpoints looks like, is the documentation of Stripe (https://docs.stripe.com/api).
Although documentation of endpoints is a nice resource, the data layer on the FE requires a very high degree of duplication of things that are already developed on the BE. Stripe solves this by not only providing extensive documentation of the REST endpoints, but also an easy-to-use SDK that allows developers to integrate with their services. After some investigation and finding some great resources that extend on the OpenApi spec, we found that Stripe most likely auto-generates their sdk’s based on the spec that is auto-generated based on their api’s. Since we build api’s in a very similar fashion and already output such a spec we dug further into the auto-generation of the client side code as well.
OpenAPI specification
Let’s discuss the OpenApi spec more in depth before continuing. It is a comprehensive specification that describes a REST api using JSON or XML format. It has been widely used for more than a decade (https://en.wikipedia.org/wiki/OpenAPI_Specification). We have been relying on it for multiple of our products for years as well. Since the specification is so clear and unambiguous that it can be generated from server code, the transformation from the specification into client code is equally straightforward. The specification also serves as an interface to map across programming languages. A BE written in GO or Rust can generate the same specification which, in turn, can be transformed into any FE language such as Kotlin or Typescript.
OpenAPI SDK generation
After exploring different tools, we opted for OpenAPI Generator to generate the client side sdk from our OpenApi specification(https://openapi-generator.tech/). To validate this approach, we first rewrote our integration tests on the BE. We found a number of advantages of using this approach. The first advantage is the validation of the generated sdk during the development of the API. By testing through the generated sdk the BE engineer can already validate that everything is working and all the necessary data is required and provided by the sdk. The second advantage is that it increases development speed and reduces small mistakes. By having a completely typed sdk the IDE can already help developers by flagging mistakes a lot sooner. This was not possible in our previous setup where endpoints were called by typing a url. An example snippet of the raw implementation can be found in image 2 and an example with the generated SDK can be seen in image 3.
The final step was to implement it in our FE applications. With everything being tested on the BE to serve as examples, we were able to roll out the use of the sdk on the FE in a matter of days. This change resulted in a higher degree of type safety across the stack, increase in development speed and experience for the FE team and simplified communication between FE and BE.
Closing statement
Efficient knowledge-sharing between FE and BE is crucial to develop high-quality software. Therefore, we always try to document our API and leverage tooling to keep the API documentation up-to-date. However, with the generation of an sdk, we can take this one step further and ensure that we can leverage type hinting in our IDE while writing tests in the back-end or during development of the front-end side of the application. This streamlines our development process and helps us to create valuable products for our clients.
See also
Are you looking for an entrepreneurial digital partner? Reach out to [email protected] or schedule a call