|
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