TypeScript REST API Client
Tags: typescript
Published: 2020-05-22 21:44:13

In this article, I will introduce a list of REST API client libraries I've researched which can be used in TypeScript (browser or  Node.js).

### Summary

* [axios](https://github.com/axios/axios) and [typed-rest-client](https://github.com/Microsoft/typed-rest-client) have many users and stable development activities.
  * As of Nov. 2019, axios is more popular than typed-rest-client. However, typed-rest-client might be going to get popularity in the future as it is maintained by Microsoft, that also maintains TypeScript.
* [Fetch API](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API/Using_Fetch), which is a good option based on Web standard is not fully supported in all browsers, and some additional codes are required to support types.
  * Using [Polyfill](https://github.com/github/fetch) would solve the browser support problem.
* Generating client SDK with [OpenAPI Generator](https://openapi-generator.tech/) will save a lot when OpenAPI (Swagger) spec is available.
  * OpenAPI Generator is a project that was forked from [Swagger Codegen](https://swagger.io/tools/swagger-codegen/) and maintained by a community. It has more active development and more generators than Swagger Codegen. (cf. [Swagger Codegen Fork: Q&A](https://openapi-generator.tech/docs/fork-qna))
  * Generators for TypeScript provided by OpenAPI Generator includes [typescript-axios](https://openapi-generator.tech/docs/generators/typescript-axios), [typescript-fetch](https://openapi-generator.tech/docs/generators/typescript-fetch) and [typescript-anglar](https://openapi-generator.tech/docs/generators/typescript-angular), that is made especially for Angular framework. (cf. [Generators List](https://openapi-generator.tech/docs/generators#client-generators))

### Examples of Using Libraries

#### OpenAPI Generator

##### Generate a Client SDK

CLI tool can be install in various ways such as NPM or Docker image. (cf. [CLI Installation](https://openapi-generator.tech/docs/installation.html))

Generators that don't depend on a specific framework are the ones using axios or Fetch API. As I mentioned earlier, I chose [typescript-axios](https://openapi-generator.tech/docs/generators/typescript-axios). You can generate a client SDK in your src directory with the following command.

```shell
openapi-generator generate -g typescript-axios -i ./openapi.yaml -o ./src/client-axios
```

##### Call an API with SDK

You can change the base URL when a URL specified in OpenAPI document is different from the actual one.


```typescript
import { DefaultApi } from '@/client-axios';

const baseUrl = 'https://jsonplaceholder.typicode.com';
new DefaultApi({ basePath: baseUrl }).getToDo(1).then((res) => {
  console.log(res.data);
})
```

In case generated codes violate linter rules in your project, you need to configure the linter to ignore them.

```bash
# .eslintignore
src/client-axios
```

Also, when your project uses webpack and configures the type definition to use only `webpack-env`, you need to add a type definitions of Node.js modules because generated codes use url module in Node.js. (cf. [TypeScript Configuration Reference](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#types-typeroots-and-types))

```javascript
// tsconfig.json
{
  "compilerOptions": {
    "types": ["webpack-env", "node"]
  }
}
```

#### axios

Define interface for response bodies and pass them as type parameters in axios API.

```typescript
interface Todo {
  userId: number,
  id: number,
  title: string,
  completed: boolean,
}
```

```typescript
import axios from 'axios';

const url = 'https://jsonplaceholder.typicode.com/todos/1';
axios.get<Todo>(url).then((res) => {
  console.log(res.data);
});
```

### Reference

* How to generate client libraries from OpenAPI
	* https://blog.5thfloor.co.jp/2019/06/26/webapp-development-with-openapi-and-typescript/#openapi-generator-api-
	* https://ky-yk-d.hatenablog.com/entry/2019/01/13/234108
* [Vue.js Cookbook](https://vuejs.org/v2/cookbook/using-axios-to-consume-apis.html)
	*  It recommends axios as there still are some problems with Fetch API.