|
1 | 1 | <img src="../../docs/public/assets/openapi-fetch.svg" alt="openapi-fetch" width="216" height="40" /> |
2 | 2 |
|
3 | | -openapi-fetch applies your OpenAPI types to the native fetch API via TypeScript. Weighs in at **1 kb** and has virtually zero runtime. Works with React, Vue, Svelte, or vanilla JS. |
| 3 | +openapi-fetch applies your OpenAPI types to the native fetch API via TypeScript. Weighs in at **2 kb** and has virtually zero runtime. Works with React, Vue, Svelte, or vanilla JS. |
4 | 4 |
|
5 | 5 | | Library | Size (min) | |
6 | 6 | | :----------------------------- | ---------: | |
7 | | -| **openapi-fetch** | `1 kB` | |
| 7 | +| **openapi-fetch** | `2 kB` | |
8 | 8 | | **openapi-typescript-fetch** | `4 kB` | |
9 | 9 | | **openapi-typescript-codegen** | `345 kB` | |
10 | 10 |
|
@@ -104,133 +104,6 @@ const { data, error } = await put("/blogposts", { |
104 | 104 | }); |
105 | 105 | ``` |
106 | 106 |
|
107 | | -### Pathname |
| 107 | +## 📓 Docs |
108 | 108 |
|
109 | | -The pathname of `get()`, `put()`, `post()`, etc. **must match your schema literally.** Note in the example, the URL is `/blogposts/{post_id}`. This library will replace all `path` params for you (so they can be typechecked) |
110 | | - |
111 | | -> ✨ **Tip** |
112 | | -> |
113 | | -> openapi-fetch infers types from the URL. Prefer static string values over dynamic runtime values, e.g.: |
114 | | -> |
115 | | -> - ✅ `"/blogposts/{post_id}"` |
116 | | -> - ❌ `[...pathParts].join("/") + "{post_id}"` |
117 | | -
|
118 | | -### Request |
119 | | - |
120 | | -The `get()` request shown needed the `params` object that groups <a href="https://spec.openapis.org/oas/latest.html#parameter-object" target="_blank" rel="noopener noreferrer">parameters by type</a> (`path` or `query`). If a required param is missing, or the wrong type, a type error will be thrown. |
121 | | - |
122 | | -The `post()` request required a `body` object that provided all necessary <a href="https://spec.openapis.org/oas/latest.html#request-body-object" target="_blank" rel="noopener noreferrer">requestBody</a> data. |
123 | | - |
124 | | -### Response |
125 | | - |
126 | | -All methods return an object with **data**, **error**, and **response**. |
127 | | - |
128 | | -- **data** will contain that endpoint’s `2xx` response if the server returned `2xx`; otherwise it will be `undefined` |
129 | | -- **error** likewise contains that endpoint’s `4xx`/`5xx` response if the server returned either; otherwise it will be `undefined` |
130 | | - - _Note: `default` will also be interpreted as `error`, since its intent is handling unexpected HTTP codes_ |
131 | | -- **response** has response info like `status`, `headers`, etc. It is not typechecked. |
132 | | - |
133 | | -## Version Support |
134 | | - |
135 | | -openapi-fetch implements the [native fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) which is available in all major browsers. |
136 | | - |
137 | | -If using in a Node.js environment, version 18 or greater is recommended (newer is better). |
138 | | - |
139 | | -TypeScript support is pretty far-reaching as this library doesn’t use any cutting-edge features, but using the latest version of TypeScript is always recommended for accuracy. |
140 | | - |
141 | | -## API |
142 | | - |
143 | | -### Create Client |
144 | | - |
145 | | -**createClient** accepts the following options, which set the default settings for all subsequent fetch calls. |
146 | | - |
147 | | -```ts |
148 | | -createClient<paths>(options); |
149 | | -``` |
150 | | - |
151 | | -| Name | Type | Description | |
152 | | -| :---------------- | :-------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
153 | | -| `baseUrl` | `string` | Prefix all fetch URLs with this option (e.g. `"https://myapi.dev/v1/"`). | |
154 | | -| `fetch` | `fetch` | Fetch function used for requests (defaults to `globalThis.fetch`) | |
155 | | -| `querySerializer` | QuerySerializer | (optional) Serialize query params for all requests (default: `new URLSearchParams()`) | |
156 | | -| `bodySerializer` | BodySerializer | (optional) Serialize request body object for all requests (default: `JSON.stringify()`) | |
157 | | -| (Fetch options) | | Any valid fetch option (`headers`, `mode`, `cache`, `signal` …) (<a href="https://developer.mozilla.org/en-US/docs/Web/API/fetch#options" target="_blank" rel="noopener noreferrer">docs</a>) | |
158 | | - |
159 | | -### Fetch options |
160 | | - |
161 | | -The following options apply to all request methods (`.get()`, `.post()`, etc.) |
162 | | - |
163 | | -```ts |
164 | | -client.get("/my-url", options); |
165 | | -``` |
166 | | - |
167 | | -| Name | Type | Description | |
168 | | -| :---------------- | :---------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
169 | | -| `params` | ParamsObject | Provide `path` and `query` params from the OpenAPI schema | |
170 | | -| `params.path` | `{ [name]: value }` | Provide all `path` params (params that are part of the URL) | |
171 | | -| `params.query` | `{ [name]: value }` | Provide all `query params (params that are part of the <a href="https://developer.mozilla.org/en-US/docs/Web/API/URL/searchParams" target="_blank" rel="noopener noreferrer">searchParams</a> | |
172 | | -| `body` | `{ [name]:value }` | The <a href="https://spec.openapis.org/oas/latest.html#request-body-object" target="_blank" rel="noopener noreferrer">requestBody</a> data, if needed (PUT/POST/PATCH/DEL only) | |
173 | | -| `querySerializer` | QuerySerializer | (optional) Serialize query params for this request only (default: `new URLSearchParams()`) | |
174 | | -| `bodySerializer` | BodySerializer | (optional) Serialize request body for this request only (default: `JSON.stringify()`) | |
175 | | -| `parseAs` | `"json"` \| `"text"` \| `"arrayBuffer"` \| `"blob"` \| `"stream"` | Parse the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Response/body" target="_blank" rel="noopener noreferrer">response body</a>, with `"stream"` skipping processing altogether (default: `"json"`) | |
176 | | -| (Fetch options) | | Any valid fetch option (`headers`, `mode`, `cache`, `signal` …) (<a href="https://developer.mozilla.org/en-US/docs/Web/API/fetch#options" target="_blank" rel="noopener noreferrer">docs</a>) | |
177 | | - |
178 | | -### querySerializer |
179 | | - |
180 | | -This library uses <a href="https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams" target="_blank" rel="noopener noreferrer">URLSearchParams</a> to <a href="https://swagger.io/docs/specification/serialization/" target="_blank" rel="noopener noreferrer">serialize query parameters</a>. For complex query param types (e.g. arrays) you’ll need to provide your own `querySerializer()` method that transforms query params into a URL-safe string: |
181 | | - |
182 | | -```ts |
183 | | -const { data, error } = await get("/search", { |
184 | | - params: { |
185 | | - query: { tags: ["food", "california", "healthy"] }, |
186 | | - }, |
187 | | - querySerializer(q) { |
188 | | - let s = ""; |
189 | | - for (const [k, v] of Object.entries(q)) { |
190 | | - if (Array.isArray(v)) { |
191 | | - s += `${k}[]=${v.join(",")}`; |
192 | | - } else { |
193 | | - s += `${k}=${v}`; |
194 | | - } |
195 | | - } |
196 | | - return s; // ?tags[]=food&tags[]=california&tags[]=healthy |
197 | | - }, |
198 | | -}); |
199 | | -``` |
200 | | - |
201 | | -### bodySerializer |
202 | | - |
203 | | -Similar to [querySerializer](#querySerializer), bodySerializer works for requestBody. You probably only need this when using `multipart/form-data`: |
204 | | - |
205 | | -```ts |
206 | | -const { data, error } = await put("/submit", { |
207 | | - body: { |
208 | | - name: "", |
209 | | - query: { version: 2 }, |
210 | | - }, |
211 | | - bodySerializer(body) { |
212 | | - const fd = new FormData(); |
213 | | - for (const [k, v] of Object.entries(body)) { |
214 | | - fd.append(k, v); |
215 | | - } |
216 | | - return fd; |
217 | | - }, |
218 | | -}); |
219 | | -``` |
220 | | - |
221 | | -If your `body` is already a `FormData`, provide an identity function: |
222 | | - |
223 | | -```ts |
224 | | -const { data, error } = await put("/submit", { |
225 | | - body: myFormData, |
226 | | - bodySerializer: (body) => body, |
227 | | -}); |
228 | | -``` |
229 | | - |
230 | | -For `multipart/form-data`, [do not set the `Content-Type` header](https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects#sending_files_using_a_formdata_object). The browser will set that for you, along with the boundary expression, which serves as a delimiter for the form fields. |
231 | | - |
232 | | -## 🎯 Project Goals |
233 | | - |
234 | | -1. Infer types automatically from OpenAPI schemas **without generics** (or, only the absolute minimum needed) |
235 | | -2. Respect the native `fetch()` API while reducing boilerplate (such as `await res.json()`) |
236 | | -3. Be as small and light as possible |
| 109 | +[View Docs](https://openapi-ts.pages.dev/openapi-fetch/) |
0 commit comments