Software architect | Full stack developer
"There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies" C.A.R. Hoare
Real Programmers Don't Write Code, They Generate Code - Frontend and Backend Communication2022-02-09
What is DTO?
When communicating with the backend, we need to regularly ensure that we continuously maintain the compatibility of the communication models. These models are commonly called DTO (Data Transfer Objects). This name distinguishes them from database models, which may contain more information. For example, a user model may contain the following fields:
When communicating with the frontend, we shouldn’t send the ‘password’ field, therefore our DTO should look like this:
When we have tens, hundreds, or thousands of these models in an application, the whole process of writing them can be very time-consuming, and prone to errors or simple typos. Then in addition there is the entire service code used for communication, and together that is a huge amount of code. But what if all this could be generated automatically without having to write a single line?
Swagger / OpenAPI
In 2011, Swagger was created to describe the API structure in a convenient JSON or YAML format. This format has been developed since, and under its new name, OpenAPI, enables to describe models and endpoints for communication of any given system. An example of an OpenAPI document looks like this.
When creating the API we can highlight two main approaches:
- 1. Code first - we write the code, and on its basis we determine the API structure
- 2. Contract first - we write the API structure in OpenAPI format, and then create the backend and frontend that will work on the basis of this structure
In this article we will look at case 1 (Code First) as it is the most common and universal.
The Backend Build
Endpoint APIs are grouped into controllers and methods. On the code side of the backend, it is a regular class method that does some work and returns a value. Suppose that we already have a code ready for our API, in order to describe the structure we need to mark the endpoints appropriately: Example in Java Spring:
Example in C# (.NET)
After such marking, generally under the address /swagger.json we will have the description of our API available in the format in which we can use to generate the client.
Automation - generating API client
Openapi-generator https://github.com/OpenAPITools/openapi-generator serves as a useful tool for generating clients. It is able to generate all data models and services for communication. Firstly, the OpenAPI generator reads the description (swagger.json) and then generates an API client on the base of the selected generator. There are several available for TypeScript. By following this link: https://openapi-generator.tech/docs/generators/
You will find a complete list of generators. As you can see, there are many generators with which we can generate the client and even the server codes (when we are working according to the contract-first approach).
We install them with the help of npm
We create the openapitools.json file in the root project directory
Then we should add the action in package.json which will be used for this:
Using a generated client
The complete client consists of models (DTOs) and services. What is DTO was described on begining. Service a complete logic which is required to load data.
Example autogenerated service looks like that:
As you can see the generator has created a method for getting health check. By implementing it anywhere, we can perform a direct operation on the API: