Skip to content

Commit 077d9a0

Browse files
committed
migrate ru guides
1 parent c6826b3 commit 077d9a0

12 files changed

Lines changed: 2430 additions & 0 deletions

File tree

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
---
2+
title: Обработка API-запросов
3+
sidebar:
4+
order: 4
5+
---
6+
7+
import { Tabs, TabItem } from '@astrojs/starlight/components';
8+
import { FileTree } from '@astrojs/starlight/components';
9+
import { Aside } from '@astrojs/starlight/components';
10+
11+
## API-запросы в `shared` \{#shared-api-requests\}
12+
13+
Начните с размещения общей логики API-запросов в каталоге `shared/api`. Это упрощает повторное использование запросов во всем приложении, что ускоряет разработку. Для многих проектов этого будет достаточно.
14+
15+
Типичная структура файлов будет такой:
16+
17+
<FileTree>
18+
- shared
19+
- api
20+
- client.ts
21+
- index.ts
22+
- endpoints
23+
- login.ts
24+
</FileTree>
25+
26+
Файл `client.ts` централизует настройку HTTP-запросов. Он оборачивает выбранный вами подход (например, `fetch()` или экземпляр `axios`) и обрабатывает общие конфигурации, такие как:
27+
28+
- Базовый URL бэкенда.
29+
- Заголовки по умолчанию (например, для аутентификации).
30+
- Сериализация данных.
31+
32+
Вот примеры для `axios` и `fetch`:
33+
34+
<Tabs>
35+
36+
<TabItem label="Axios">
37+
```ts title="shared/api/client.ts"
38+
// Example using axios
39+
import axios from 'axios';
40+
41+
export const client = axios.create({
42+
baseURL: 'https://your-api-domain.com/api/',
43+
timeout: 5000,
44+
headers: { 'X-Custom-Header': 'my-custom-value' }
45+
});
46+
```
47+
</TabItem>
48+
49+
<TabItem label="Fetch">
50+
```ts title="shared/api/client.ts"
51+
export const client = {
52+
async post(endpoint: string, body: any, options?: RequestInit) {
53+
const response = await fetch(`https://your-api-domain.com/api${endpoint}`, {
54+
method: 'POST',
55+
body: JSON.stringify(body),
56+
...options,
57+
headers: {
58+
'Content-Type': 'application/json',
59+
'X-Custom-Header': 'my-custom-value',
60+
...options?.headers,
61+
},
62+
});
63+
return response.json();
64+
}
65+
// ... другие методы put, delete, и т.д.
66+
};
67+
```
68+
</TabItem>
69+
70+
</Tabs>
71+
72+
Организуйте свои отдельные функции API-запросов в shared/api/endpoints, группируя их по API эндпоинтам.
73+
74+
<Aside>
75+
76+
Для простоты, в примерах ниже мы опускаем взаимодействие с формами и валидацию. Для получения подробной информации о том, как работать с такими библиотеками как Zod или Valibot, обратитесь к секции [Проверка типов и схемы](/docs/guides/examples/types#type-validation-schemas-and-zod).
77+
78+
</Aside>
79+
80+
```ts title="shared/api/endpoints/login.ts"
81+
import { client } from '../client';
82+
83+
export interface LoginCredentials {
84+
email: string;
85+
password: string;
86+
}
87+
88+
export function login(credentials: LoginCredentials) {
89+
return client.post('/login', credentials);
90+
}
91+
```
92+
93+
Используйте файл `index.ts` в `shared/api` для экспорта ваших функций запросов.
94+
95+
```ts title="shared/api/index.ts"
96+
export { client } from './client'; // Если нужно экспортировать клиент
97+
export { login } from './endpoints/login';
98+
export type { LoginCredentials } from './endpoints/login';
99+
```
100+
101+
## API-запросы, специфичные для слайса \{#slice-specific-api-requests\}
102+
103+
Если API-запрос используется только определенным слайсом (например, одной страницей или фичей) и не будет использоваться повторно, поместите его в сегмент `api` этого слайса. Это позволит аккуратно отделить логику, специфичную для слайса, от всего остального приложения.
104+
105+
<FileTree>
106+
- pages
107+
- login
108+
- index.ts
109+
- api
110+
- login.ts
111+
- ui
112+
- LoginPage.tsx
113+
</FileTree>
114+
115+
```ts title="pages/login/api/login.ts"
116+
import { client } from 'shared/api';
117+
118+
interface LoginCredentials {
119+
email: string;
120+
password: string;
121+
}
122+
123+
export function login(credentials: LoginCredentials) {
124+
return client.post('/login', credentials);
125+
}
126+
```
127+
128+
Вам не нужно экспортировать функцию `login()` через публичный API страницы, потому что маловероятно, что какое-либо другое место в приложении будет нуждаться в этом запросе.
129+
130+
<Aside>
131+
132+
Избегайте преждевременного размещения API-запросов и типов ответов бэкенда в слое `entities`. Ответы бэкенда могут отличаться от того, что нужно вашим сущностям фронтенда. Логика API в `shared/api` или сегменте `api` слайса позволяет вам преобразовывать данные при необходимости, сохраняя фокус сущностей на проблемах фронтенда.
133+
134+
</Aside>
135+
136+
## Использование генераторов клиентов \{#client-generators\}
137+
138+
Если ваш бэкенд предоставляет OpenAPI спецификацию, инструменты как [orval](https://orval.dev/) или [openapi-typescript](https://openapi-ts.dev/), могут генерировать типы API и функции запросов. Разместите сгенерированный код, например, в `shared/api/openapi`. Обязательно включите `README.md` для документирования того, что это за типы и как их генерировать.
139+
140+
## Интеграция с библиотеками состояния сервера \{#server-state-libraries\}
141+
142+
При использовании библиотек состояния сервера, таких как [TanStack Query (React Query)](https://tanstack.com/query/latest) или [Pinia Colada](https://pinia-colada.esm.dev/) вам может потребоваться совместное использование типов или ключей кеша между срезами. Используйте общий слой `shared` для таких вещей, как:
143+
144+
- Типы данных API
145+
- Ключи кеша
146+
- Общие параметры запросов и мутаций
147+
148+
Подробнее о том, как работать с server state библиотеками, читайте в статье [React Query](/docs/guides/tech/with-react-query)

0 commit comments

Comments
 (0)