Output
Learn about files generated with @hey-api/openapi-ts
.
TIP
Your actual output depends on your Hey API configuration. It may contain a different number of files and their contents might differ.
Overview
If you use the default configuration, your project might look like this.
my-app/
├── node_modules/
├── src/
│ ├── client/
│ │ ├── index.ts
│ │ ├── sdk.gen.ts
│ │ └── types.gen.ts
│ └── index.ts
└── package.json
Each file is an artifact generated by a Hey API plugin. This is the default output, we will cover customizing it on this page. These files also form the base for third-party plugins.
Let's go through each file in the src/client
folder and explain what it looks like, what it does, and how to use it.
TypeScript
TypeScript interfaces are located in the types.gen.ts
file. This is the only file that does not impact your bundle size and runtime performance. It will get discarded during build time, unless you configured to emit runtime enums.
This file contains three different categories of interfaces created from your input:
- reusable components
- operation request, response, and error data
- enums
Depending on your input and configuration, some of these categories might be missing or differ in your output (and that's okay!).
export type Pet = {
id?: number;
name: string;
};
export type AddPetData = {
body: Pet;
};
export type AddPetResponse = Pet;
As you can see, everything is exported from types.gen.ts
. You can import individual exports in your application and use them as necessary.
Configuration
You can modify the contents of types.gen.ts
by configuring the @hey-api/typescript
plugin. Note that you must specify the default plugins to preserve the default output.
import { defaultPlugins } from '@hey-api/openapi-ts';
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
...defaultPlugins,
{
name: '@hey-api/typescript',
// ...custom options
},
],
};
Enums
By default, @hey-api/openapi-ts
will only emit enums as types. You may want to generate runtime artifacts. A good use case is iterating through possible field values without manually typing arrays. To emit runtime enums, set enums
to a valid option.
import { defaultPlugins } from '@hey-api/openapi-ts';
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
...defaultPlugins,
{
enums: false, // default
name: '@hey-api/typescript',
},
],
};
import { defaultPlugins } from '@hey-api/openapi-ts';
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
...defaultPlugins,
{
enums: 'javascript',
name: '@hey-api/typescript',
},
],
};
import { defaultPlugins } from '@hey-api/openapi-ts';
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
...defaultPlugins,
{
enums: 'typescript',
name: '@hey-api/typescript',
},
],
};
We recommend exporting enums as plain JavaScript objects. TypeScript enums are not a type-level extension of JavaScript and pose typing challenges.
SDKs
SDKs are located in the sdk.gen.ts
file. SDKs are abstractions on top of clients and serve the same purpose. By default, @hey-api/openapi-ts
will generate a flat SDK layer. Your choice to use SDKs depends on personal preferences and bundle size considerations.
Flat SDKs
This is the default setting. Flat SDKs support tree-shaking and can lead to reduced bundle size over duplicated client calls. The function names are generated from operation IDs or operation location.
Class SDKs
Class SDKs do not support tree-shaking which will lead to increased bundle sizes, but some people prefer this option for syntax reasons. The class names are generated from operation tags and method names are generated from operation IDs or operation location.
No SDKs
If you prefer to use clients directly or do not need the SDK layer, define plugins
manually and omit the @hey-api/sdk
plugin. Type support for clients is currently limited due to popularity of other options. If you'd like to use this option and need better types, please open an issue.
Configuration
You can modify the contents of sdk.gen.ts
by configuring the @hey-api/sdk
plugin. Note that you must specify the default plugins to preserve the default output.
import { defaultPlugins } from '@hey-api/openapi-ts';
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
...defaultPlugins,
{
asClass: false, // default
name: '@hey-api/sdk',
},
],
};
import { defaultPlugins } from '@hey-api/openapi-ts';
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
...defaultPlugins,
{
asClass: true,
name: '@hey-api/sdk',
},
],
};
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
'@hey-api/typescript',
'@hey-api/sdk',
],
};
Output
Below are different outputs depending on your chosen style. No SDKs approach will not generate the sdk.gen.ts
file.
import { client, type Options } from '@hey-api/client-fetch';
import type { AddPetData, AddPetError, AddPetResponse } from './types.gen';
export const addPet = (options: Options<AddPetData>) =>
(options?.client ?? client).post<AddPetResponse, AddPetError>({
...options,
url: '/pet',
});
import { client, type Options } from '@hey-api/client-fetch';
import type { AddPetData, AddPetError, AddPetResponse } from './types.gen';
export class PetService {
public static addPet(options: Options<AddPetData>) {
return (options?.client ?? client).post<AddPetResponse, AddPetError>({
...options,
url: '/pet',
});
}
}
Usage
This is how you'd make the same request using each approach.
import { addPet } from './client/sdk.gen';
addPet({
body: {
name: 'Kitty',
},
});
import { PetService } from './client/sdk.gen';
PetService.addPet({
body: {
name: 'Kitty',
},
});
import { client } from '@hey-api/client-fetch';
client.post({
body: {
name: 'Kitty',
},
url: '/pet',
});
JSON Schemas
Schemas are located in the schemas.gen.ts
file. This file contains runtime schemas generated from your OpenAPI specification definitions located in #/components/schemas
. If you're using OpenAPI 3.1, your schemas are fully JSON Schema compliant and can be used with other tools supporting JSON Schema.
Configuration
You can modify the contents of schemas.gen.ts
by configuring the @hey-api/schemas
plugin. Note that you must specify the default plugins to preserve the default output.
import { defaultPlugins } from '@hey-api/openapi-ts';
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
...defaultPlugins,
{
name: '@hey-api/schemas',
type: 'json',
},
],
};
import { defaultPlugins } from '@hey-api/openapi-ts';
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
...defaultPlugins,
{
name: '@hey-api/schemas',
type: 'form',
},
],
};
import { defaultPlugins } from '@hey-api/openapi-ts';
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
...defaultPlugins,
'@hey-api/schemas',
],
};
Output
Below is an example output generated in the type: 'form'
style. Disabling schemas will not generate the schemas.gen.ts
file.
export const PetSchema = {
required: ['name'],
properties: {
id: {
type: 'integer',
format: 'int64',
example: 10,
},
name: {
type: 'string',
example: 'doggie',
},
},
type: 'object',
} as const;
Usage
A great use case for schemas is client-side form input validation.
import { $Schema } from './client/schemas.gen';
const maxInputLength = $Schema.properties.text.maxLength;
if (userInput.length > maxInputLength) {
throw new Error(`Text length can't exceed ${maxInputLength} characters!`);
}
Index
For convenience, every artifact generated by default plugins is re-exported from index.ts
. However, we recommend importing artifacts from their files to avoid ambiguity.
import type { Pet } from './client'; // [!code --] // 👎
import type { Pet } from './client/types.gen'; // [!code ++] // 👍
Client
Client package files are located in the client
folder. This folder will include different files depending on which client you're using. This folder isn't generated by default. If you want to bundle client packages into your output, read the Bundling section.
Plugins
The default output generated by Hey API plugins already allows you to build robust clients. However, you might be working with third-party packages and wishing to automate more of your boilerplate. The Plugins page covers this topic and more.
Examples
You can view live examples on StackBlitz.
Sponsoring
Love Hey API? Please consider becoming a sponsor.