DEV Community

Carlos V.
Carlos V.

Posted on • Updated on

How to generate a TypeScript client from a Swagger documented API

In my previous tutorial, I built a simple REST API with Swagger documentation. Check it out:

In this tutorial, I will generate a TypeScript client code based on the Swagger documentation and use it on a simple React application (it can be any front-end application).

Why we want to do something like this? First of all, it's better to have one a single source of truth for the contracts in our server-client architecture. Otherwise, one change can break all our consumers.

For this process, I'm gonna use swagger-typescript-api. I've seen this tool constantly evolving throughout the last year, its maintainers are doing an awesome job.

First of all, I bootstrap a React app using create-react-app (CRA) with a TypeScript template, of course 💅

npx create-react-app react-mini-swagger-client --template typescript
Enter fullscreen mode Exit fullscreen mode

Somewhere else, I have my previous flask-mini-rest up and running in localhost:5000. (Recently I pushed some changes in order to support CORS and improve the Swagger model documentation).

CRA places all the source files inside ./src directory, so I will generate my TS client there.

npx swagger-typescript-api -p http://127.0.0.1:5000/api/v1/swagger.json -o ./src/apiClient --modular
Enter fullscreen mode Exit fullscreen mode

swagger-typescript-api is pretty cool, it can be run with npx and it support many flags documented in its repo. It generates 3 files for my API

File Description
Items.ts It exports the main client to be used on our application. Each method of the Items class is one public endpoint. Types were read from the Swagger docs.
data-contracts.ts Are the API models or return types.
http-client.ts This is the code responsible to actually fetch the data to the server.

Let's start the development server:

npm start
Enter fullscreen mode Exit fullscreen mode

Now it comes the interesting part. How to use the generated TS client. I'm going to write some simple examples on how to use the TS client in the src/App.tsx file which is the only one with the bootstrapped app logic.

Let's initialize the API client which is declared in the Items.ts module:

const api = new Items({
  baseUrl: "http://localhost:5000/api/v1",
});
Enter fullscreen mode Exit fullscreen mode

If your app is running a in a production server, the baseUrl path should point to the appropriate API URL.

To get all the Items:

const res = await api.getItemsApi();
setItems(res.data);  // This set the response to the `items` state
Enter fullscreen mode Exit fullscreen mode

Let's suppose we want to insert a new item in the API in a form button:

<button
  onClick={async () => {
    const item: Item = {  // `Item` is imported from the data-contracts
      id,  // this is a variable with the form input
      name,  // this is a variable with the form input
    };
    await api.postItemsApi(item);
    props.setItems([...props.items, item]);
  }}
>
  Add
</button>
Enter fullscreen mode Exit fullscreen mode

It's pretty similar with the getItemApi which gets a simple Item resource.

As you can see, it's pretty simple to use, self-documented and strongly-typed. Having a well defined back-end contract you can ensure robustness and type-safety front-end communication. The types generated can be used in many ways, TypeScript project references for example. Types can be shared among many consumers. My friend and mentor, Fernanda, presented a great talk in this topic called Don't Break the Contract: Keep Consistency with Full Stack Type Safety, please give it a look.

Also, an automated job can generate the a new TS client triggered by some event. But still it's up to us to update the consumers. Hopefully the unit tests can detect breaking changes.

Check out a full working code in my repo. Sorry that I didn't follow all the best practices as I only wanted to show how to use this TS client.

Mini example of swagger-typescript-api

This project was bootstrapped with Create React App.

npx create-react-app react-mini-swagger-client --template typescript

And API client was generated with swagger-typescript-api.

npx swagger-typescript-api -p http://127.0.0.1:5000/api/v1/swagger.json -o ./src/apiClient --modular

... while running flask-mini-rest app.

Run the app

In the project directory, you can run:

npm start

Runs the app in the development mode.
Open http://localhost:3000 to view it in the browser.

The page will reload if you make edits.
You will also see any lint errors in the console.

License

MIT

Top comments (3)

Collapse
 
po5i profile image
Carlos V.

Thanks @own_alazzam10 . Unfortunately, link is broken