OpenAPI EBO integration

This article describes OpenAPI development process integration within EBO.

What problems do we want to solve?

Within EBO, there are no programming dependencies between the frontend and the backend codebases, as we have backend endpoints being consumed by the frontend.

This results in the following problems: - no CI checks for changes which are made on frontend or backend - no type spelling and prompts in IDE means poor DX - lack of possibility to generate types and code - mostly manual work when introducing new endpoints, which involves building code infrastructure on the frontend side.

Also, we would like to have a nice human-readable documentation of our endpoints.

What is proposed?

EBO API which is exposed and is used by browser application is a Rest API. Today the standard de-facto for describing Rest API is OpenAPI initiative. As the official website says: The OpenAPI Specification is a specification language for HTTP APIs that provides a standardised means to define your API to others. Moreover we already use OpenAPI for Ebury API.

OpenAPI is proposed as a specification language to describe EBO API endpoints.

How is OpenAPI definition integrated with the codebase?

To leverage all advantages of using OpenAPI it should be integrated with the codebase, development and deployment stages.

EBO API is defined in one file openapi.json under the api folder in the eburyonline repository. The file is included and tracked by git, which means that every time a developer wants to make changes in EBO API they must reflect those changes in this file.

Using the openapi.json file, documentation as well as code can be created for backend and frontend development requirements. Documentation and code for backend and frontend development. Documentation should represent an HTML based page, which could be published or explored locally by developers who have eburyonline repository access.

Generated code is not part of the git repository and should be generated every time a developer uses the repository for development or deployment reasons. As a result after cloning the repository, generated code will be generated while the serving(generating) script is running.

Diagram - OpenAPI as source of truth

To have and track a connection between the frontend, backend and openapi.json we’ll introduce new CI pipeline steps. These steps are executed before compiling the codebase and use openapi.json as source of truth.

Diagram - CI pipeline

Using generated types in the EBO codebase we can trace changes in any of three subjects of our api system: openapi.json, EBO backend and EBO frontend.

For example during the normal flow when we write openapi,json, define endpoint, generate types and functions from it and use this code in endpoint implementation on backend and on frontend, any time we change something in openapi.json and that modification is against frontend codebase or backend types generated from it, we’ll have an error and failed CI. This will prevent us from random changing in any of these three api contract points and let us keep those in monolith.

OpenAPI definition

All the changes in EBO endpoints are introduced by changing a file which could be found by path: api/openapi.json within the eburyonline repository. The openapi.json file is a part of the eburyonline repository.

The version of OpenAPI specification which is used in openapi.json is 3.1+.

All entities within one openapi.json file should be unique. There shouldn't be a Payment entity in one endpoint definition(A) and another Payment entity with different structure in another endpoint definition(B). In this case Payment entity should be narrowed with names(APayment, BPayment) or generalised and put on top of endpoints as general entity type with name Payment. In other words all entities should be unique.

All endpoints must have a response with status code 200 defined.

Code generating

Any user of EBO API could generate any type of code introspecting openapi.json. The common rule is that generated code depends on openapi.json and never vice versa.

Within the frontend we generate types and api-client functions and place this code under the frontend/src/api/generated folder. This folder is not part of the repository and is generated locally on developer laptop or in a CI pipeline. Api client functions are used to reach out api endpoints declared in openapi.json as well as generated types are used in TS code.

Within the backend we generate python types and must use those implementing endpoint functionality.

Normal developer flow

Developers pull eburyonline repository, run the noted script and all necessary code is generated automatically. If developers pull a new version of openapi.json they should restart the specific script and regenerate code.

API human readable documentation

Documentation can be displayed by any tool, of which there are many.