Skip to content

Commit 4917ce2

Browse files
authored
Add openapi-fetch to readme (#1064)
1 parent 206f285 commit 4917ce2

File tree

1 file changed

+39
-59
lines changed

1 file changed

+39
-59
lines changed

README.md

Lines changed: 39 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
[![codecov](https://codecov.io/gh/drwpow/openapi-typescript/branch/main/graph/badge.svg)](https://codecov.io/gh/drwpow/openapi-typescript)
44

55
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
6+
67
[![All Contributors](https://img.shields.io/badge/all_contributors-67-orange.svg?style=flat-square)](#contributors-)
8+
79
<!-- ALL-CONTRIBUTORS-BADGE:END -->
810

911
# 📘️ openapi-typescript
@@ -52,7 +54,6 @@ npx openapi-typescript "specs/**/*.yaml" --output schemas/
5254

5355
_Thanks, [@sharmarajdaksh](https://github.com/sharmarajdaksh)!_
5456

55-
5657
#### ☁️ Reading remote schemas
5758

5859
```bash
@@ -90,98 +91,77 @@ _Thanks, [@gr2m](https://github.com/gr2m)!_
9091

9192
#### ⚾ Fetching data
9293

93-
##### Simple example
94-
95-
Any fetch call can be typed from the `paths` like so:
96-
97-
```ts
98-
import { paths } from './my-types';
99-
100-
const response: paths["/api/v1/user/{user_id}"]["get"][200 | 500] = await fetch(`/api/v1/user/${user_id}`).then((res) => res.json());
101-
```
102-
103-
Or if you add the `--path-params-as-types` CLI flag, you can take advantage of more automatic inference:
104-
105-
```ts
106-
import { paths } from './my-types';
107-
108-
const url = `/api/v1/user/${user_id}`;
109-
const response: paths[url]["get"][200 | 500] = await fetch(url).then((res) => res.json());
110-
```
94+
Fetching data can be done simply and safely using an **automatically-typed fetch wrapper**:
11195

112-
##### openapi-typescript-fetch
96+
- [openapi-fetch](https://github.com/drwpow/openapi-fetch) (recommended)
97+
- [openapi-typescript-fetch](https://www.npmjs.com/package/openapi-typescript-fetch) by [@ajaishankar](https://github.com/ajaishankar)
11398

114-
You can generate a fully-typed [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) client from openapiTS types with the [openapi-typescript-fetch](https://www.npmjs.com/package/openapi-typescript-fetch) package:
99+
**Example** ([openapi-fetch](https://github.com/drwpow/openapi-fetch))
115100

116101
```ts
117-
import { paths } from "./petstore";
118-
import { Fetcher } from "openapi-typescript-fetch";
119-
120-
const fetcher = Fetcher.for<paths>();
102+
import createClient from "openapi-fetch";
103+
import { paths } from "./v1"; // (generated from openapi-typescript)
121104

122-
// GET
123-
const findPetsByStatus = fetcher.path("/pet/findByStatus").method("get").create();
124-
const { status, data: pets } = await findPetsByStatus({
125-
status: ["available", "pending"],
105+
const { get, post, put, patch, del } = createClient<paths>({
106+
baseURL: "https://myserver.com/api/v1/",
107+
headers: {
108+
Authorization: `Bearer ${import.meta.env.VITE_AUTH_TOKEN}`,
109+
},
126110
});
127-
128-
// POST
129-
const addPet = fetcher.path("/pet").method("post").create();
130-
await addPet({ ... })
131111
```
132112

133-
[See docs](https://www.npmjs.com/package/openapi-typescript-fetch)
113+
See each project’s respective pages for usage & install instructions.
134114

135-
_Thanks, [@ajaishankar](https://github.com/ajaishankar)!_
115+
**Tip**: Automatically-typed fetch wrappers are better to use than manually-assigned generics. The latter is not only more work, but it can be error-prone (which makes your OpenAPI typing worthless if it can’t catch all your errors!).
136116

137117
### 📖 Options
138118

139119
The following flags can be appended to the CLI command.
140120

141-
| Option | Alias | Default | Description |
142-
| :----------------------------- | :---- | :------: | :--------------------------------------------------------------------------------------------------------------------------- |
143-
| `--help` | | | Display inline help message and exit |
144-
| `--version` | | | Display this library’s version and exit |
145-
| `--output [location]` | `-o` | (stdout) | Where should the output file be saved? |
146-
| `--auth [token]` | | | Provide an auth token to be passed along in the request (only if accessing a private schema) |
147-
| `--header` | `-x` | | Provide an array of or singular headers as an alternative to a JSON object. Each header must follow the `key: value` pattern |
148-
| `--headers-object="{…}"` | `-h` | | Provide a JSON object as string of HTTP headers for remote schema request. This will take priority over `--header` |
149-
| `--http-method` | `-m` | `GET` | Provide the HTTP Verb/Method for fetching a schema from a remote URL |
150-
| `--immutable-types` | | `false` | Generates immutable types (readonly properties and readonly array) |
151-
| `--additional-properties` | | `false` | Allow arbitrary properties for all schema objects without `additionalProperties: false` |
152-
| `--empty-objects-unknown` | | `false` | Allow arbitrary properties for schema objects with no specified properties, and no specified `additionalProperties` |
153-
| `--default-non-nullable` | | `false` | Treat schema objects with default values as non-nullable |
154-
| `--export-type` | `-t` | `false` | Export `type` instead of `interface` |
155-
| `--path-params-as-types` | | `false` | Allow dynamic string lookups on the `paths` object |
156-
| `--support-array-length` | | `false` | Generate tuples using array `minItems` / `maxItems` |
157-
| `--alphabetize` | | `false` | Sort types alphabetically |
121+
| Option | Alias | Default | Description |
122+
| :------------------------ | :---- | :------: | :--------------------------------------------------------------------------------------------------------------------------- |
123+
| `--help` | | | Display inline help message and exit |
124+
| `--version` | | | Display this library’s version and exit |
125+
| `--output [location]` | `-o` | (stdout) | Where should the output file be saved? |
126+
| `--auth [token]` | | | Provide an auth token to be passed along in the request (only if accessing a private schema) |
127+
| `--header` | `-x` | | Provide an array of or singular headers as an alternative to a JSON object. Each header must follow the `key: value` pattern |
128+
| `--headers-object="{…}"` | `-h` | | Provide a JSON object as string of HTTP headers for remote schema request. This will take priority over `--header` |
129+
| `--http-method` | `-m` | `GET` | Provide the HTTP Verb/Method for fetching a schema from a remote URL |
130+
| `--immutable-types` | | `false` | Generates immutable types (readonly properties and readonly array) |
131+
| `--additional-properties` | | `false` | Allow arbitrary properties for all schema objects without `additionalProperties: false` |
132+
| `--empty-objects-unknown` | | `false` | Allow arbitrary properties for schema objects with no specified properties, and no specified `additionalProperties` |
133+
| `--default-non-nullable` | | `false` | Treat schema objects with default values as non-nullable |
134+
| `--export-type` | `-t` | `false` | Export `type` instead of `interface` |
135+
| `--path-params-as-types` | | `false` | Allow dynamic string lookups on the `paths` object |
136+
| `--support-array-length` | | `false` | Generate tuples using array `minItems` / `maxItems` |
137+
| `--alphabetize` | | `false` | Sort types alphabetically |
158138

159139
#### 🚩 `--path-params-as-types`
160140

161141
By default, your URLs are preserved exactly as-written in your schema:
162142

163143
```ts
164144
export interface paths {
165-
'/user/{user_id}': components["schemas"]["User"];
145+
"/user/{user_id}": components["schemas"]["User"];
166146
}
167147
```
168148

169149
Which means your type lookups also have to match the exact URL:
170150

171151
```ts
172-
import { paths } from './my-schema';
152+
import { paths } from "./my-schema";
173153

174154
const url = `/user/${id}`;
175-
type UserResponses = paths['/user/{user_id}']['responses'];
155+
type UserResponses = paths["/user/{user_id}"]["responses"];
176156
```
177157

178158
But when `--path-params-as-types` is enabled, you can take advantage of dynamic lookups like so:
179159

180160
```ts
181-
import { paths } from './my-schema';
161+
import { paths } from "./my-schema";
182162

183163
const url = `/user/${id}`;
184-
type UserResponses = paths[url]['responses']; // automatically matches `paths['/user/{user_id}']`
164+
type UserResponses = paths[url]["responses"]; // automatically matches `paths['/user/{user_id}']`
185165
```
186166

187167
Though this is a contrived example, you could use this feature to automatically infer typing based on the URL in a fetch client or in some other useful place in your application.
@@ -233,7 +213,7 @@ import fs from "node:fs";
233213
import openapiTS from "openapi-typescript";
234214
235215
// example 1: load [object] as schema (JSON only)
236-
const schema = await fs.promises.readFile("spec.json", "utf8") // must be OpenAPI JSON
216+
const schema = await fs.promises.readFile("spec.json", "utf8"); // must be OpenAPI JSON
237217
const output = await openapiTS(JSON.parse(schema));
238218
239219
// example 2: load [string] as local file (YAML or JSON; released in v4.0)
@@ -251,7 +231,7 @@ The Node API may be useful if dealing with dynamically-created schemas, or you
251231
The Node API supports all the [CLI flags](#--options) above in `camelCase` format, plus the following additional options:
252232

253233
| Name | Type | Default | Description |
254-
|:----------------|:----------:|:--------|:---------------------------------------------------------------------------------|
234+
| :-------------- | :--------: | :------ | :------------------------------------------------------------------------------- |
255235
| `commentHeader` | `string` | | Override the default “This file was auto-generated …” file heading |
256236
| `inject` | `string` | | Inject arbitrary TypeScript types into the start of the file |
257237
| `transform` | `Function` | | Override the default Schema Object ➝ TypeScript transformer in certain scenarios |

0 commit comments

Comments
 (0)