dfx-openapi
dfx-openapi
is a type-safe Angular HttpClient that pulls in your OpenAPI schema.
It has virtually zero runtime and is fully compatible with Http Interceptors.
The syntax is inspired by openapi-fetch.
import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { createOpenAPIHttpClient } from 'dfx-openapi';
import type { paths } from './my-openapi-3-schema';
export function injectAPI() {
const httpClient = inject(HttpClient);
return createOpenAPIHttpClient<paths>(httpClient, { baseUrl: 'https://myapi.dev/v1/' });
}
@Injectable()
export class YourService {
private api = injectAPI();
getItem(itemId: string) {
return this.api.get('/items/{item_id}', {
params: {
path: {
item_id: '1234',
},
},
});
}
updateItem(id: string, name: string) {
return this.api.put('/items', {
body: {
id,
name,
},
});
}
}
get()
, put()
, post()
, etc. are thin wrappers around the Angular HttpClient.
Notice there are no generics, and no manual typing.
Your endpoint’s request and response were inferred automatically.
This is a huge improvement in the type safety of your endpoints because every manual assertion could lead to a bug!
This eliminates all of the following:
- ✅ No typos in URLs or params
- ✅ All parameters, request bodies, and responses are type-checked and 100% match your schema
- ✅ No manual typing of your API
- ✅ Eliminates any types that hide bugs
- ✅ Also eliminates as type overrides that can also hide bugs
Setup
Install this library along with openapi-typescript:
npm i dfx-openapi
npm i -D openapi-typescript
Highly recommended
Enable noUncheckedIndexedAccess in your tsconfig.json
(docs)
Next, generate TypeScript types from your OpenAPI schema using openapi-typescript:
npx openapi-typescript ./path/to/api/v1.yaml -o ./src/app/api/v1.d.ts
Basic usage
The best part about using dfx-openapi over oldschool codegen is no documentation needed.
dfx-openapi encourages using your existing OpenAPI documentation rather than trying to find what function to import, or what parameters that function wants:
import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { createOpenAPIHttpClient } from 'dfx-openapi';
import type { paths } from './my-openapi-3-schema';
export function injectAPI() {
const httpClient = inject(HttpClient);
return createOpenAPIHttpClient<paths>(httpClient, { baseUrl: 'https://myapi.dev/v1/' });
}
@Injectable()
export class YourService {
private api = injectAPI();
getItem(itemId: string) {
return this.api.get('/items/{item_id}', {
params: {
path: {
item_id: '1234',
},
},
});
}
updateItem(id: string, name: string) {
return this.api.put('/items', {
body: {
id,
name,
},
});
}
}
- The HTTP method is pulled directly from
createOpenAPIHttpClient()
- You pass in your desired path to
get()
, put()
, etc. - TypeScript takes over the rest and returns helpful errors for anything missing or invalid
Pathname
The pathname of get()
, put()
, post()
, etc. must match your schema literally.
Note in the example, the URL is /items/{item_id}
.
This library will quickly replace all path
params for you (so they can be typechecked).
TIP
dfx-openapi infers types from the URL.
Prefer static string values over dynamic runtime values, e.g.:
- ✅
"/items/{item_id}"
- ❌
[...pathParts].join("/") + "{item_id}"
This library also supports the label and matrix serialization styles as well (docs) automatically.
Request
The get()
request shown needed the params
object that groups parameters by type (path
or query
).
If a required param is missing, or the wrong type, a type error will be thrown.
The post()
and put()
request required a body
object that provided all necessary requestBody data.
Support
Platform | Support |
---|
Angular | >=18.0 |
openapi-typescript-helpers | >=0.0.13 |