Type sharing in OpenAPI Fullstack projects
Tags: typescript, javascript, architecture, beginners
Published: 2023-09-25 07:55:34

From the very beginning of working in my current project, we have been experiencing an issue of code reusability across the Front and Back of our application. We had a lot of code that was duplicated and often also included issues that created problems for us later on.

At the beginning, we were focusing on developing new features nad functionalities, so things like Code Reusability had to be added to the `Nice to Have` list. But, this has changed recently and right now we have a budget and resources to work on improving our project and its development.

In this article, I would like to share with you how we have solved one of our problems -> Type Sharing. Thanks to that, you will be able to implement this or similiar solution from the very beginning of working in your project (or add it afterwards just as we did).

![Code Reusability](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zjmzf6mh8dorrufz8jzy.png)

The solutions has proven to be quite useful and with the addition of ~10 lines of code (mainly CI/CD scripts) we were able to reduce the amount of static TS code by hundreds of lines.

Enjoy!

## Idea

Let's share a little background about the project technology stack, as the solution that I will talk about might not suit all projects (and most probably wont suit all of them).

The application is composed out of two main pillars:

1. Vue 3 SPA Frontend application
2. Nest.js REST Backend Modular Monolith

In both projects, we use TypeScript everywhere - from components & composables, to services & controllers.

On the backend, we are using Swagger to generate Open API documentation and playground.

This swagger can be configured to not only generate documentation but also the `api.json` file that contains all Open API schema that later on can be easily used in other tools.

For local development you can do something like this:

```ts
const document = SwaggerModule.createDocument(app, config);
writeFileSync('api.json', JSON.stringify(document))
```

You can read more about this Swagger Module here https://docs.nestjs.com/openapi/introduction

![Swagger](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fezu8hc55c90x1k0h7pq.png)

This newly generated file will contain all types and available operations for your Backend.

After generating this file, you can then consume it in your frontend application like this:

```bash
npx openapi-typescript ./backend/api.json -o ./frontend/schema.d.ts
```

This will generate a schema file will all the types generated by the Open API specification. Magic 🪄

You can use it in your frontend application like following:

```ts
import { components } from '../../schema';

type User = components['schemas']['User']
```

And you will have full type safety and autocompletion. When I first used it, I instantly felt that this is an amazing feature that could help us a lot.

## Summary

This approach is not only about reusability and reducing the lines of code that need to be maintained. It is also about maintaining the contract between Frontend and the Backend. By using one type both in Front and Back, we are making sure that we are not missing any data or passing a wrong parameter name (which is also great for further updating the project types). You can read more about it https://pactflow.io/how-pact-works/?utm_source=ossdocs&utm_campaign=getting_started#slide-1

This is just an example. To make this work fully, you would probably need to also add this schema generation both on frontend and the backend to your CI/CD pipeline so that everything is done automatically and kept in sync :)

In my case, this solution helped a lot. I hope that it will help you as well!