这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
8 changes: 4 additions & 4 deletions docs/.vitepress/config/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ export default defineConfig({
link: '/openapi-ts/clients/axios',
text: 'Axios',
},
{
link: '/openapi-ts/clients/ky',
text: 'Ky',
},
{
link: '/openapi-ts/clients/next-js',
text: 'Next.js',
Expand All @@ -115,10 +119,6 @@ export default defineConfig({
link: '/openapi-ts/clients/got',
text: 'Got <span data-soon>soon</span>',
},
{
link: '/openapi-ts/clients/ky',
text: 'Ky <span data-soon>soon</span>',
},
],
link: '/openapi-ts/clients',
text: 'Clients',
Expand Down
2 changes: 1 addition & 1 deletion docs/openapi-ts/clients.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ Hey API natively supports the following clients.
- [Fetch API](/openapi-ts/clients/fetch)
- [Angular](/openapi-ts/clients/angular)
- [Axios](/openapi-ts/clients/axios)
- [Ky](/openapi-ts/clients/ky)
- [Next.js](/openapi-ts/clients/next-js)
- [Nuxt](/openapi-ts/clients/nuxt)
- [OFetch](/openapi-ts/clients/ofetch)
- [Effect](/openapi-ts/clients/effect) <span data-soon>Soon</span>
- [Got](/openapi-ts/clients/got) <span data-soon>Soon</span>
- [Ky](/openapi-ts/clients/ky) <span data-soon>Soon</span>

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).

Expand Down
2 changes: 1 addition & 1 deletion docs/openapi-ts/clients/angular.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ When we installed the client above, it created a [`client.gen.ts`](/openapi-ts/o

### `setConfig()`

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.
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.

```js
import { client } from 'client/client.gen';
Expand Down
2 changes: 1 addition & 1 deletion docs/openapi-ts/clients/axios.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ When we installed the client above, it created a [`client.gen.ts`](/openapi-ts/o

### `setConfig()`

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.
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.

```js
import { client } from 'client/client.gen';
Expand Down
2 changes: 1 addition & 1 deletion docs/openapi-ts/clients/fetch.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ When we installed the client above, it created a [`client.gen.ts`](/openapi-ts/o

### `setConfig()`

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.
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.

```js
import { client } from 'client/client.gen';
Expand Down
305 changes: 299 additions & 6 deletions docs/openapi-ts/clients/ky.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,311 @@
---
title: Ky client
description: Ky client for Hey API. Compatible with all our features.
title: Ky v1 Client
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.
---

<script setup lang="ts">
import FeatureStatus from '@components/FeatureStatus.vue';
import AuthorsList from '@components/AuthorsList.vue';
import Heading from '@components/Heading.vue';
import VersionLabel from '@components/VersionLabel.vue';
import { sebastiaanWouters } from '@data/people.js';
</script>

# Ky <span data-soon>soon</span>

<FeatureStatus issueNumber=2794 name="Ky" />
<Heading>
<h1>Ky<span class="sr-only"> v1</span></h1>
<VersionLabel value="v1" />
</Heading>

### About

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

The Ky client for Hey API generates a type-safe client from your OpenAPI spec, fully compatible with validators, transformers, and all core features.

### Collaborators

<AuthorsList :people="[sebastiaanWouters]" />

## Features

- seamless integration with `@hey-api/openapi-ts` ecosystem
- type-safe response data and errors
- response data validation and transformation
- access to the original request and response
- granular request and response customization options
- minimal learning curve thanks to extending the underlying technology
- support bundling inside the generated output

## Installation

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:

::: code-group

```js [config]
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: ['@hey-api/client-ky'], // [!code ++]
};
```

```sh [cli]
npx @hey-api/openapi-ts \
-i hey-api/backend \
-o src/client \
-c @hey-api/client-ky # [!code ++]
```

:::

## Configuration

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.

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.

### `setConfig()`

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.

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

client.setConfig({
baseUrl: 'https://example.com',
});
```

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.

### Runtime API

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.

```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
{
name: '@hey-api/client-ky',
runtimeConfigPath: './src/hey-api.ts', // [!code ++]
},
],
};
```

In our custom file, we need to export a `createClientConfig()` method. This function is a simple wrapper allowing us to override configuration values.

::: code-group

```ts [hey-api.ts]
import type { CreateClientConfig } from './client/client.gen';

export const createClientConfig: CreateClientConfig = (config) => ({
...config,
baseUrl: 'https://example.com',
});
```

:::

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.

### `createClient()`

You can also create your own client instance. You can use it to manually send requests or point it to a different domain.

```js
import { createClient } from './client/client';

const myClient = createClient({
baseUrl: 'https://example.com',
});
```

You can also pass this instance to any SDK function through the `client` option. This will override the default instance from `client.gen.ts`.

```js
const response = await getFoo({
client: myClient,
});
```

### SDKs

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.

```js
const response = await getFoo({
baseUrl: 'https://example.com', // <-- override default configuration
});
```

## Interceptors

Interceptors (middleware) can be used to modify requests before they're sent or responses before they're returned to your application.

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.

### Example: Request interceptor

::: code-group

```js [use]
import { client } from 'client/client.gen';

async function myInterceptor(request) {
// do something
return request;
}

interceptorId = client.interceptors.request.use(myInterceptor);
```

```js [eject]
import { client } from 'client/client.gen';

// eject by ID
client.interceptors.request.eject(interceptorId);

// eject by reference
client.interceptors.request.eject(myInterceptor);
```

```js [update]
import { client } from 'client/client.gen';

async function myNewInterceptor(request) {
// do something
return request;
}

// update by ID
client.interceptors.request.update(interceptorId, myNewInterceptor);

// update by reference
client.interceptors.request.update(myInterceptor, myNewInterceptor);
```

:::

### Example: Response interceptor

::: code-group

```js [use]
import { client } from 'client/client.gen';

async function myInterceptor(response) {
// do something
return response;
}

interceptorId = client.interceptors.response.use(myInterceptor);
```

```js [eject]
import { client } from 'client/client.gen';

// eject by ID
client.interceptors.response.eject(interceptorId);

// eject by reference
client.interceptors.response.eject(myInterceptor);
```

```js [update]
import { client } from 'client/client.gen';

async function myNewInterceptor(response) {
// do something
return response;
}

// update by ID
client.interceptors.response.update(interceptorId, myNewInterceptor);

// update by reference
client.interceptors.response.update(myInterceptor, myNewInterceptor);
```

:::

::: tip
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()`.
:::

## Auth

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.

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

client.setConfig({
auth: () => '<my_token>', // [!code ++]
baseUrl: 'https://example.com',
});
```

If you're not using SDKs or generating auth, using interceptors is a common approach to configuring auth for each request.

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

client.interceptors.request.use((request, options) => {
request.headers.set('Authorization', 'Bearer <my_token>'); // [!code ++]
return request;
});
```

## Build URL

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.

```ts
type FooData = {
path: {
fooId: number;
};
query?: {
bar?: string;
};
url: '/foo/{fooId}';
};

const url = client.buildUrl<FooData>({
path: {
fooId: 1,
},
query: {
bar: 'baz',
},
url: '/foo/{fooId}',
});
console.log(url); // prints '/foo/1?bar=baz'
```

## Custom Instance

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.

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

client.setConfig({
ky: ky.create({
/* custom `ky` instance */
}),
});
```

You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom instance to be.

## API

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.

<!--@include: ../../partials/examples.md-->
<!--@include: ../../partials/sponsors.md-->
2 changes: 1 addition & 1 deletion docs/openapi-ts/clients/next-js.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ With this approach, `client.gen.ts` will call `createClientConfig()` before init

### `setConfig()`

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.
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.

```js
import { client } from 'client/client.gen';
Expand Down
2 changes: 1 addition & 1 deletion docs/openapi-ts/clients/nuxt.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ When we installed the client above, it created a [`client.gen.ts`](/openapi-ts/o

### `setConfig()`

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.
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.

```js
import { client } from 'client/client.gen';
Expand Down
Loading
Loading