Skip to content
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
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.