Skip to content
6 changes: 6 additions & 0 deletions i18n/en/code.json
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,12 @@
"message": "in any other way",
"description": "Variant for contribute (link)"
},
"shared.translationBanner.base": {
"message": "This documentation has been automatically translated and may contain errors. For the authoritative version, please refer to the "
},
"shared.translationBanner.link": {
"message": "English Documentation"
},
"theme.NotFound.title": {
"message": "Page Not Found",
"description": "The title of the 404 page"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ sidebar_position: 4
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Handling API Requests
# Handling API Requests {#handling-api-requests}

## Shared API Requests
## Shared API Requests {#shared-api-requests}

Start by placing common API request logic in the `shared/api` directory. This makes it easy to reuse requests across your application and helps with faster prototyping. For many projects, this is all you'll need for API calls.

Expand Down Expand Up @@ -93,7 +93,7 @@ export { login } from './endpoints/login';
export type { LoginCredentials } from './endpoints/login';
```

## Slice-Specific API Requests
## Slice-Specific API Requests {#slice-specific-api-requests}

If an API request is only used by a specific slice (like a single page or feature) and won't be reused, place it in the api segment of that slice. This keeps slice-specific logic neatly contained.

Expand Down Expand Up @@ -126,11 +126,11 @@ Avoid placing API calls and response types in the `entities` layer prematurely.

:::

## Using Client Generators
## Using Client Generators {#client-generators}

If your backend has an OpenAPI specification, tools like [orval](https://orval.dev/) or [openapi-typescript](https://openapi-ts.dev/) can generate API types and request functions for you. Place the generated code in, for example, `shared/api/openapi`. Make sure to include `README.md` to document what those types are, and how to generate them.

## Integrating with Server State Libraries
## Integrating with Server State Libraries {#server-state-libraries}

When using server state libraries like [TanStack Query (React Query)](https://tanstack.com/query/latest) or [Pinia Colada](https://pinia-colada.esm.dev/) you might need to share types or cache keys between slices. Use the `shared` layer for things like:

Expand Down
6 changes: 6 additions & 0 deletions i18n/ja/code.json
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,12 @@
"message": "貢献する",
"description": "Variant for contribute (link)"
},
"shared.translationBanner.base": {
"message": "このドキュメントは自動翻訳されており、誤りを含む可能性があります。公式版については、以下を参照してください。"
},
"shared.translationBanner.link": {
"message": "英語のドキュメント"
},
"theme.NotFound.title": {
"message": "ページが見つかりません",
"description": "The title of the 404 page"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
---
sidebar_position: 4
title: APIリクエストの処理
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import TranslationBanner from "@site/src/shared/ui/translation-banner/tmpl.mdx"

<TranslationBanner />

# APIリクエストの処理 {#handling-api-requests}

## 共有APIリクエスト {#shared-api-requests}

共通のAPIリクエストロジックは`shared/api`ディレクトリに配置することから始めます。これにより、アプリケーション全体でリクエストを簡単に再利用でき、プロトタイピングの高速化に役立ちます。多くのプロジェクトでは、API呼び出しに必要なのはこれだけです。

典型的なファイル構造は次のようになります。
- 📂 shared
- 📂 api
- 📄 client.ts
- 📄 index.ts
- 📂 endpoints
- 📄 login.ts

`client.ts`ファイルは、HTTPリクエストの設定を一元化します。選択したメソッド(`fetch()`や`axios`インスタンスなど)をラップし、次のような共通の設定を処理します。

- バックエンドのベースURL
- デフォルトヘッダー(認証用など)
- データシリアライゼーション

`axios`と`fetch`の例を以下に示します。

<Tabs>

<TabItem value="axios" label="Axios">
```ts title="shared/api/client.ts"
// Example using axios
import axios from 'axios';

export const client = axios.create({
baseURL: 'https://your-api-domain.com/api/',
timeout: 5000,
headers: { 'X-Custom-Header': 'my-custom-value' }
});
```
</TabItem>

<TabItem value="fetch" label="Fetch">
```ts title="shared/api/client.ts"
export const client = {
async post(endpoint: string, body: any, options?: RequestInit) {
const response = await fetch(`https://your-api-domain.com/api${endpoint}`, {
method: 'POST',
body: JSON.stringify(body),
...options,
headers: {
'Content-Type': 'application/json',
'X-Custom-Header': 'my-custom-value',
...options?.headers,
},
});
return response.json();
}
// ... other methods like put, delete, etc.
};
```
</TabItem>

</Tabs>

個々のAPIリクエスト関数は`shared/api/endpoints`に、APIエンドポイントごとにグループ化して整理します。

:::note

例をわかりやすくするために、フォームのインタラクションとバリデーションは省略しています。ZodやValibotのようなライブラリの詳細については、[Type Validation and Schemas](/docs/guides/examples/types#type-validation-schemas-and-zod)の記事を参照してください。

:::

```ts title="shared/api/endpoints/login.ts"
import { client } from '../client';

export interface LoginCredentials {
email: string;
password: string;
}

export function login(credentials: LoginCredentials) {
return client.post('/login', credentials);
}
```

`shared/api`の`index.ts`ファイルを使用して、リクエスト関数をエクスポートします。

```ts title="shared/api/index.ts"
export { client } from './client'; // If you want to export the client itself
export { login } from './endpoints/login';
export type { LoginCredentials } from './endpoints/login';
```

## スライス固有のAPIリクエスト {#slice-specific-api-requests}

APIリクエストが特定のスライス(単一のページや機能など)でのみ使用され、再利用されない場合は、そのスライスのapiセグメントに配置します。これにより、スライス固有のロジックがきちんと整理されます。

- 📂 pages
- 📂 login
- 📄 index.ts
- 📂 api
- 📄 login.ts
- 📂 ui
- 📄 LoginPage.tsx

```ts title="pages/login/api/login.ts"
import { client } from 'shared/api';

interface LoginCredentials {
email: string;
password: string;
}

export function login(credentials: LoginCredentials) {
return client.post('/login', credentials);
}
```

このリクエストがアプリケーションの他の場所で必要になる可能性は低いので、ページの公開APIで`login()`関数をエクスポートする必要はありません。

:::note

API呼び出しとレスポンスの型を`entities`レイヤーに時期尚早に配置することは避けてください。バックエンドのレスポンスは、フロントエンドのエンティティが必要とするものと異なる場合があります。`shared/api`またはスライスの`api`セグメントのAPIロジックを使用すると、データを適切に変換でき、エンティティをフロントエンドの懸念事項に集中させることができます。

:::

## クライアントジェネレーターの使用 {#client-generators}

バックエンドにOpenAPI仕様がある場合、[orval](https://orval.dev/)や[openapi-typescript](https://openapi-ts.dev/)のようなツールでAPIの型とリクエスト関数を生成できます。生成されたコードは、たとえば`shared/api/openapi`に配置します。これらの型が何であるか、そしてそれらを生成する方法を文書化するために、`README.md`を含めるようにしてください。

## サーバーステートライブラリとの統合 {#server-state-libraries}

[TanStack Query (React Query)](https://tanstack.com/query/latest)や[Pinia Colada](https://pinia-colada.esm.dev/)のようなサーバーステートライブラリを使用する場合、スライス間で型やキャッシュキーを共有する必要があるかもしれません。次のようなものには`shared`レイヤーを使用します。

- APIデータ型
- キャッシュキー
- 共通のクエリ/ミューテーションオプション
6 changes: 6 additions & 0 deletions i18n/kr/code.json
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,12 @@
"message": "다른 방식으로",
"description": "Variant for contribute (link)"
},
"shared.translationBanner.base": {
"message": "이 문서는 자동으로 번역되었으므로 오류가 포함될 수 있습니다. 공식 버전을 확인하시려면 다음을 참조하십시오 "
Comment thread
illright marked this conversation as resolved.
Outdated
},
"shared.translationBanner.link": {
"message": "영어 문서"
},
"theme.NotFound.title": {
"message": "페이지를 찾을 수 없습니다",
"description": "The title of the 404 page"
Expand Down
6 changes: 6 additions & 0 deletions i18n/ru/code.json
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,12 @@
"message": "любым другим способом",
"description": "Variant for contribute (link)"
},
"shared.translationBanner.base": {
"message": "Эта документация переведена автоматически и может содержать неточности. За проверенной версией обращайтесь к "
},
"shared.translationBanner.link": {
"message": "английской документации"
},
"theme.NotFound.title": {
"message": "Страница не найдена",
"description": "The title of the 404 page"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
---
sidebar_position: 4
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Обработка API-запросов {#handling-api-requests}

## API-запросы в `shared` {#shared-api-requests}

Начните с размещения общей логики API-запросов в каталоге `shared/api`. Это упрощает повторное использование запросов во всем приложении и помогает ускорить прототипирование. Для многих проектов этого будет достаточно для вызовов API.
Comment thread
Solant marked this conversation as resolved.
Outdated

Типичная структура файлов будет такой:
- 📂 shared
- 📂 api
- 📄 client.ts
- 📄 index.ts
- 📂 endpoints
- 📄 login.ts

Файл `client.ts` централизует настройку HTTP-запросов. Он оборачивает выбранный вами подход (например, `fetch()` или экземпляр `axios`) и обрабатывает общие конфигурации, такие как:

- Базовый URL бэкенда.
- Заголовки по умолчанию (например, для аутентификации).
- Сериализация данных.

Вот примеры для `axios` и `fetch`:

<Tabs>

<TabItem value="axios" label="Axios">
```ts title="shared/api/client.ts"
// Example using axios
import axios from 'axios';

export const client = axios.create({
baseURL: 'https://your-api-domain.com/api/',
timeout: 5000,
headers: { 'X-Custom-Header': 'my-custom-value' }
});
```
</TabItem>

<TabItem value="fetch" label="Fetch">
```ts title="shared/api/client.ts"
export const client = {
async post(endpoint: string, body: any, options?: RequestInit) {
const response = await fetch(`https://your-api-domain.com/api${endpoint}`, {
method: 'POST',
body: JSON.stringify(body),
...options,
headers: {
'Content-Type': 'application/json',
'X-Custom-Header': 'my-custom-value',
...options?.headers,
},
});
return response.json();
}
// ... другие методы put, delete, и т.д.
};
```
</TabItem>

</Tabs>

Организуйте свои отдельные функции API-запросов в shared/api/endpoints, группируя их по API эндпоинтам.

:::note

Для простоты, в примерах ниже мы опускаем взаимодействие с формами и валидацию. Для получения подробной информации о том как работать с такими библиотеками как Zod или Valibot, обратитесь к статье [Проверка типов и схемы](/docs/guides/examples/types#type-validation-schemas-and-zod).
Comment thread
Solant marked this conversation as resolved.
Outdated

:::

```ts title="shared/api/endpoints/login.ts"
import { client } from '../client';

export interface LoginCredentials {
email: string;
password: string;
}

export function login(credentials: LoginCredentials) {
return client.post('/login', credentials);
}
```

Используйте файл `index.ts` в `shared/api` для экспорта ваших функций запросов.

```ts title="shared/api/index.ts"
export { client } from './client'; // Если нужно экспортировать клиент
export { login } from './endpoints/login';
export type { LoginCredentials } from './endpoints/login';
```

## API-запросы, специфичные для слайса {#client-generators}
Comment thread
Solant marked this conversation as resolved.
Outdated

Если API-запрос используется только определенным слайсом (например, одной страницей или функцией) и не будет использоваться повторно, поместите его в сегмент api этого слайса. Это позволит аккуратно хранить логику, специфичную для слайса.
Comment thread
Solant marked this conversation as resolved.
Outdated

- 📂 pages
- 📂 login
- 📄 index.ts
- 📂 api
- 📄 login.ts
- 📂 ui
- 📄 LoginPage.tsx

```ts title="pages/login/api/login.ts"
import { client } from 'shared/api';

interface LoginCredentials {
email: string;
password: string;
}

export function login(credentials: LoginCredentials) {
return client.post('/login', credentials);
}
```

Вам не нужно экспортировать функцию `login()` через публичный API страницы, потому что маловероятно, что какое-либо другое место в приложении будет нуждаться в этом запросе.

:::note

Избегайте преждевременного размещения вызовов API и типов ответов в слое `entities`. Ответы бэкенда могут отличаться от того, что нужно вашим сущностям фронтенда. Логика API в `shared/api` или сегменте `api` слайса позволяет вам преобразовывать данные при необходимости, сохраняя фокус сущностей на проблемах фронтенда.
Comment thread
Solant marked this conversation as resolved.
Outdated

:::

## Использование генераторов клиентов {#client-generators}

Если ваш бэкенд предоставляет OpenAPI спецификацию, инструменты как [orval](https://orval.dev/) или [openapi-typescript](https://openapi-ts.dev/), могут генерировать типы API и функции запросов. Разместите сгенерированный код, например, в `shared/api/openapi`. Обязательно включите `README.md` для документирования того, что это за типы и как их генерировать.

## Интеграция с библиотеками состояния сервера {#server-state-libraries}

При использовании библиотек состояния сервера, таких как [TanStack Query (React Query)](https://tanstack.com/query/latest) или [Pinia Colada](https://pinia-colada.esm.dev/) вам может потребоваться совместное использование типов или ключей кеша между срезами. Используйте общий слой `shared` для таких вещей, как:

- Типы данных API
- Ключи кеша
- Общие параметры запросов и мутаций
Comment thread
illright marked this conversation as resolved.
6 changes: 6 additions & 0 deletions i18n/uz/code.json
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,12 @@
"message": "har qanday boshqa yo'l bilan",
"description": "Variant for contribute (link)"
},
"shared.translationBanner.base": {
"message": "Ushbu hujjat avtomatik tarzda tarjima qilingan va xatolar boʻlishi mumkin. Tasdiqlangan versiya uchun "
},
"shared.translationBanner.link": {
"message": "ingliz tilidagi hujjatlarga murojaat qiling"
},
"theme.NotFound.title": {
"message": "Sahifa topilmadi",
"description": "The title of the 404 page"
Expand Down
Loading