Skip to content

Commit c63c69b

Browse files
committed
docs: add ky client
1 parent 4c72db6 commit c63c69b

File tree

327 files changed

+90223
-80
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

327 files changed

+90223
-80
lines changed

docs/.vitepress/config/en.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ export default defineConfig({
9595
link: '/openapi-ts/clients/axios',
9696
text: 'Axios',
9797
},
98+
{
99+
link: '/openapi-ts/clients/ky',
100+
text: 'Ky',
101+
},
98102
{
99103
link: '/openapi-ts/clients/next-js',
100104
text: 'Next.js',
@@ -115,10 +119,6 @@ export default defineConfig({
115119
link: '/openapi-ts/clients/got',
116120
text: 'Got <span data-soon>soon</span>',
117121
},
118-
{
119-
link: '/openapi-ts/clients/ky',
120-
text: 'Ky <span data-soon>soon</span>',
121-
},
122122
],
123123
link: '/openapi-ts/clients',
124124
text: 'Clients',

docs/openapi-ts/clients.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ Hey API natively supports the following clients.
2828
- [Fetch API](/openapi-ts/clients/fetch)
2929
- [Angular](/openapi-ts/clients/angular)
3030
- [Axios](/openapi-ts/clients/axios)
31+
- [Ky](/openapi-ts/clients/ky)
3132
- [Next.js](/openapi-ts/clients/next-js)
3233
- [Nuxt](/openapi-ts/clients/nuxt)
3334
- [OFetch](/openapi-ts/clients/ofetch)
3435
- [Effect](/openapi-ts/clients/effect) <span data-soon>Soon</span>
3536
- [Got](/openapi-ts/clients/got) <span data-soon>Soon</span>
36-
- [Ky](/openapi-ts/clients/ky) <span data-soon>Soon</span>
3737

3838
Don't see your client? [Build your own](/openapi-ts/clients/custom) or let us know your interest by [opening an issue](https://github.com/hey-api/openapi-ts/issues).
3939

docs/openapi-ts/clients/angular.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ When we installed the client above, it created a [`client.gen.ts`](/openapi-ts/o
8787

8888
### `setConfig()`
8989

90-
This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any `HttpRequest` configuration option to `setConfig()`, and even your own [`httpClient`](#custom-httpclient) implementation.
90+
This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any `HttpRequest` configuration option to `setConfig()`, and even your own [`httpClient`](#custom-instance) implementation.
9191

9292
```js
9393
import { client } from 'client/client.gen';

docs/openapi-ts/clients/axios.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ When we installed the client above, it created a [`client.gen.ts`](/openapi-ts/o
6969

7070
### `setConfig()`
7171

72-
This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any Axios configuration option to `setConfig()` (except for `auth`), and even your own [Axios](#custom-axios) implementation.
72+
This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any Axios configuration option to `setConfig()` (except for `auth`), and even your own [Axios](#custom-instance) implementation.
7373

7474
```js
7575
import { client } from 'client/client.gen';

docs/openapi-ts/clients/fetch.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ When we installed the client above, it created a [`client.gen.ts`](/openapi-ts/o
6868

6969
### `setConfig()`
7070

71-
This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any Fetch API configuration option to `setConfig()`, and even your own [Fetch](#custom-fetch) implementation.
71+
This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any Fetch API configuration option to `setConfig()`, and even your own [Fetch](#custom-instance) implementation.
7272

7373
```js
7474
import { client } from 'client/client.gen';

docs/openapi-ts/clients/ky.md

Lines changed: 299 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,311 @@
11
---
2-
title: Ky client
3-
description: Ky client for Hey API. Compatible with all our features.
2+
title: Ky v1 Client
3+
description: Generate a type-safe Ky v1 client from OpenAPI with the Ky client for openapi-ts. Fully compatible with validators, transformers, and all core features.
44
---
55

66
<script setup lang="ts">
7-
import FeatureStatus from '@components/FeatureStatus.vue';
7+
import AuthorsList from '@components/AuthorsList.vue';
8+
import Heading from '@components/Heading.vue';
9+
import VersionLabel from '@components/VersionLabel.vue';
10+
import { sebastiaanWouters } from '@data/people.js';
811
</script>
912

10-
# Ky <span data-soon>soon</span>
11-
12-
<FeatureStatus issueNumber=2794 name="Ky" />
13+
<Heading>
14+
<h1>Ky<span class="sr-only"> v1</span></h1>
15+
<VersionLabel value="v1" />
16+
</Heading>
1317

1418
### About
1519

1620
[Ky](https://github.com/sindresorhus/ky) is a tiny and elegant JavaScript HTTP client based on the Fetch API.
1721

22+
The Ky client for Hey API generates a type-safe client from your OpenAPI spec, fully compatible with validators, transformers, and all core features.
23+
24+
### Collaborators
25+
26+
<AuthorsList :people="[sebastiaanWouters]" />
27+
28+
## Features
29+
30+
- seamless integration with `@hey-api/openapi-ts` ecosystem
31+
- type-safe response data and errors
32+
- response data validation and transformation
33+
- access to the original request and response
34+
- granular request and response customization options
35+
- minimal learning curve thanks to extending the underlying technology
36+
- support bundling inside the generated output
37+
38+
## Installation
39+
40+
In your [configuration](/openapi-ts/get-started), add `@hey-api/client-ky` to your plugins and you'll be ready to generate client artifacts. :tada:
41+
42+
::: code-group
43+
44+
```js [config]
45+
export default {
46+
input: 'hey-api/backend', // sign up at app.heyapi.dev
47+
output: 'src/client',
48+
plugins: ['@hey-api/client-ky'], // [!code ++]
49+
};
50+
```
51+
52+
```sh [cli]
53+
npx @hey-api/openapi-ts \
54+
-i hey-api/backend \
55+
-o src/client \
56+
-c @hey-api/client-ky # [!code ++]
57+
```
58+
59+
:::
60+
61+
## Configuration
62+
63+
The Ky client is built as a thin wrapper on top of Ky, extending its functionality to work with Hey API. If you're already familiar with Ky, configuring your client will feel like working directly with Ky.
64+
65+
When we installed the client above, it created a [`client.gen.ts`](/openapi-ts/output#client) file. You will most likely want to configure the exported `client` instance. There are two ways to do that.
66+
67+
### `setConfig()`
68+
69+
This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any Ky configuration option to `setConfig()`, and even your own [`ky`](#custom-instance) instance.
70+
71+
```js
72+
import { client } from 'client/client.gen';
73+
74+
client.setConfig({
75+
baseUrl: 'https://example.com',
76+
});
77+
```
78+
79+
The disadvantage of this approach is that your code may call the `client` instance before it's configured for the first time. Depending on your use case, you might need to use the second approach.
80+
81+
### Runtime API
82+
83+
Since `client.gen.ts` is a generated file, we can't directly modify it. Instead, we can tell our configuration to use a custom file implementing the Runtime API. We do that by specifying the `runtimeConfigPath` option.
84+
85+
```js
86+
export default {
87+
input: 'hey-api/backend', // sign up at app.heyapi.dev
88+
output: 'src/client',
89+
plugins: [
90+
{
91+
name: '@hey-api/client-ky',
92+
runtimeConfigPath: './src/hey-api.ts', // [!code ++]
93+
},
94+
],
95+
};
96+
```
97+
98+
In our custom file, we need to export a `createClientConfig()` method. This function is a simple wrapper allowing us to override configuration values.
99+
100+
::: code-group
101+
102+
```ts [hey-api.ts]
103+
import type { CreateClientConfig } from './client/client.gen';
104+
105+
export const createClientConfig: CreateClientConfig = (config) => ({
106+
...config,
107+
baseUrl: 'https://example.com',
108+
});
109+
```
110+
111+
:::
112+
113+
With this approach, `client.gen.ts` will call `createClientConfig()` before initializing the `client` instance. If needed, you can still use `setConfig()` to update the client configuration later.
114+
115+
### `createClient()`
116+
117+
You can also create your own client instance. You can use it to manually send requests or point it to a different domain.
118+
119+
```js
120+
import { createClient } from './client/client';
121+
122+
const myClient = createClient({
123+
baseUrl: 'https://example.com',
124+
});
125+
```
126+
127+
You can also pass this instance to any SDK function through the `client` option. This will override the default instance from `client.gen.ts`.
128+
129+
```js
130+
const response = await getFoo({
131+
client: myClient,
132+
});
133+
```
134+
135+
### SDKs
136+
137+
Alternatively, you can pass the client configuration options to each SDK function. This is useful if you don't want to create a client instance for one-off use cases.
138+
139+
```js
140+
const response = await getFoo({
141+
baseUrl: 'https://example.com', // <-- override default configuration
142+
});
143+
```
144+
145+
## Interceptors
146+
147+
Interceptors (middleware) can be used to modify requests before they're sent or responses before they're returned to your application.
148+
149+
They can be added with `use`, removed with `eject`, and updated wth `update`. The `use` and `update` methods will return the ID of the interceptor for use with `eject` and `update`. Ky does not have the interceptor functionality, so we implement our own.
150+
151+
### Example: Request interceptor
152+
153+
::: code-group
154+
155+
```js [use]
156+
import { client } from 'client/client.gen';
157+
158+
async function myInterceptor(request) {
159+
// do something
160+
return request;
161+
}
162+
163+
interceptorId = client.interceptors.request.use(myInterceptor);
164+
```
165+
166+
```js [eject]
167+
import { client } from 'client/client.gen';
168+
169+
// eject by ID
170+
client.interceptors.request.eject(interceptorId);
171+
172+
// eject by reference
173+
client.interceptors.request.eject(myInterceptor);
174+
```
175+
176+
```js [update]
177+
import { client } from 'client/client.gen';
178+
179+
async function myNewInterceptor(request) {
180+
// do something
181+
return request;
182+
}
183+
184+
// update by ID
185+
client.interceptors.request.update(interceptorId, myNewInterceptor);
186+
187+
// update by reference
188+
client.interceptors.request.update(myInterceptor, myNewInterceptor);
189+
```
190+
191+
:::
192+
193+
### Example: Response interceptor
194+
195+
::: code-group
196+
197+
```js [use]
198+
import { client } from 'client/client.gen';
199+
200+
async function myInterceptor(response) {
201+
// do something
202+
return response;
203+
}
204+
205+
interceptorId = client.interceptors.response.use(myInterceptor);
206+
```
207+
208+
```js [eject]
209+
import { client } from 'client/client.gen';
210+
211+
// eject by ID
212+
client.interceptors.response.eject(interceptorId);
213+
214+
// eject by reference
215+
client.interceptors.response.eject(myInterceptor);
216+
```
217+
218+
```js [update]
219+
import { client } from 'client/client.gen';
220+
221+
async function myNewInterceptor(response) {
222+
// do something
223+
return response;
224+
}
225+
226+
// update by ID
227+
client.interceptors.response.update(interceptorId, myNewInterceptor);
228+
229+
// update by reference
230+
client.interceptors.response.update(myInterceptor, myNewInterceptor);
231+
```
232+
233+
:::
234+
235+
::: tip
236+
To eject, you must provide the ID or reference of the interceptor passed to `use()`, the ID is the value returned by `use()` and `update()`.
237+
:::
238+
239+
## Auth
240+
241+
The SDKs include auth mechanisms for every endpoint. You will want to configure the `auth` field to pass the right token for each request. The `auth` field can be a string or a function returning a string representing the token. The returned value will be attached only to requests that require auth.
242+
243+
```js
244+
import { client } from 'client/client.gen';
245+
246+
client.setConfig({
247+
auth: () => '<my_token>', // [!code ++]
248+
baseUrl: 'https://example.com',
249+
});
250+
```
251+
252+
If you're not using SDKs or generating auth, using interceptors is a common approach to configuring auth for each request.
253+
254+
```js
255+
import { client } from 'client/client.gen';
256+
257+
client.interceptors.request.use((request, options) => {
258+
request.headers.set('Authorization', 'Bearer <my_token>'); // [!code ++]
259+
return request;
260+
});
261+
```
262+
263+
## Build URL
264+
265+
If you need to access the compiled URL, you can use the `buildUrl()` method. It's loosely typed by default to accept almost any value; in practice, you will want to pass a type hint.
266+
267+
```ts
268+
type FooData = {
269+
path: {
270+
fooId: number;
271+
};
272+
query?: {
273+
bar?: string;
274+
};
275+
url: '/foo/{fooId}';
276+
};
277+
278+
const url = client.buildUrl<FooData>({
279+
path: {
280+
fooId: 1,
281+
},
282+
query: {
283+
bar: 'baz',
284+
},
285+
url: '/foo/{fooId}',
286+
});
287+
console.log(url); // prints '/foo/1?bar=baz'
288+
```
289+
290+
## Custom Instance
291+
292+
You can provide a custom `ky` instance. This is useful if you need to extend the default instance with extra functionality, or replace it altogether.
293+
294+
```js
295+
import { client } from 'client/client.gen';
296+
297+
client.setConfig({
298+
ky: ky.create({
299+
/* custom `ky` instance */
300+
}),
301+
});
302+
```
303+
304+
You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom instance to be.
305+
306+
## API
307+
308+
You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@hey-api/client-ky/types.d.ts) interface.
309+
310+
<!--@include: ../../partials/examples.md-->
18311
<!--@include: ../../partials/sponsors.md-->

docs/openapi-ts/clients/next-js.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ With this approach, `client.gen.ts` will call `createClientConfig()` before init
8686

8787
### `setConfig()`
8888

89-
This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any Fetch API configuration option to `setConfig()`, and even your own [Fetch](#custom-fetch) implementation.
89+
This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any Fetch API configuration option to `setConfig()`, and even your own [Fetch](#custom-instance) implementation.
9090

9191
```js
9292
import { client } from 'client/client.gen';

docs/openapi-ts/clients/nuxt.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ When we installed the client above, it created a [`client.gen.ts`](/openapi-ts/o
9393

9494
### `setConfig()`
9595

96-
This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any Nuxt configuration option to `setConfig()`, and even your own [`$fetch`](#custom-fetch) implementation.
96+
This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any Nuxt configuration option to `setConfig()`, and even your own [`$fetch`](#custom-instance) implementation.
9797

9898
```js
9999
import { client } from 'client/client.gen';

0 commit comments

Comments
 (0)