Upload files to "/"
This commit is contained in:
commit
3299f9e467
125
Невеличкий гайд по http сервісу та requestʼах.md
Normal file
125
Невеличкий гайд по http сервісу та requestʼах.md
Normal file
@ -0,0 +1,125 @@
|
||||
### Пару важливих речей:
|
||||
- Метод = функція
|
||||
- Класс != тип - в TS є такі штуки як `AxiosResponse<IResponse<T>, any>` і потрібно розуміти що ці штуки працюють зовсім по другому. Навіть якщо я десь забув поправити - це важливо памʼятати
|
||||
- any = unknown - формально мені б любий Senior Typescript девелопер язика за таке відірвав, але в цілому тут воно має різницю тільки в тому що при використанні того чи іншого ESlint видає різні помилки які треба виправляти. Це typescript, розслабся і получай задоволення
|
||||
|
||||
загальний перелік інструментів та ліб:
|
||||
|
||||
- tanstack query
|
||||
- axios
|
||||
|
||||
піду з кінця:
|
||||
|
||||
коли ти хочеш відправити реквест на сервак, чи то Get чи то Post, звичайно це робиться через створений hook:
|
||||
|
||||
```ts
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { gameService } from "@/shared/services/game.service";
|
||||
import { transformApiDataToGames } from "../components/gamesSlider/gamesSlider.utils";
|
||||
|
||||
export const useGetGames = () => {
|
||||
const query = useQuery({
|
||||
queryKey: ["games"],
|
||||
queryFn: gameService.getGames,
|
||||
});
|
||||
|
||||
const games =
|
||||
query.data && query.data.length > 0
|
||||
? transformApiDataToGames(query.data)
|
||||
: [];
|
||||
|
||||
return { games, ...query };
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
тут можна побачити декілька речей:
|
||||
|
||||
- хук використовує tanstack query для реквесту
|
||||
- танстак використовує допоміжну функцію класу GameService визначену в папці shared/services/
|
||||
- Після отримання даних, воно перетворюється на локальний класс Game, достатньо незручний спосіб, краще його не використовувати, але в цьому випадку було необхідно
|
||||
|
||||
тепер як видно по цим речам, нам треба допоможна сервісна функція, яка використовує не просто fetch(), а повноцінний написаний Діаною http service:
|
||||
```ts
|
||||
import { HttpService } from "./http.service";
|
||||
import { axiosClient } from "./axios-client";
|
||||
import { IGameApiResponse } from "../types/game.types";
|
||||
|
||||
export class GameService extends HttpService {
|
||||
getGames = async () => {
|
||||
const response = await this.get<IGameApiResponse[]>(`rpg-events`);
|
||||
return response;
|
||||
};
|
||||
}
|
||||
|
||||
export const gameService = new GameService(axiosClient);
|
||||
|
||||
```
|
||||
|
||||
тут можна побачити що достає з сервака цей реквест, і що воно привʼязана до клієнта аксіоса, який і дозволяє використовувати http протокол.
|
||||
|
||||
подивившись ближче, можна побачити що в файлі https.service.ts є імплементація axiosClient - НЕ ДИВИСЬ НА НЕЇ - це дефолт, і він в нашому випадку на самий крайній випадок, справжня імплементація axiosClient яка використовується ось тут:
|
||||
```ts
|
||||
export const gameService = new GameService(axiosClient);
|
||||
```
|
||||
виходить з файлу axios-client.ts (я потратив не одну годину шукаючи і розбираючись що і де)
|
||||
|
||||
|
||||
Отже, axiosClient є імплементацією яка повністю повинна замінити fetch(), та з досвіду - працює набагато краще
|
||||
|
||||
Те що найголовніше для фетчингу ігор є в цій функції get:
|
||||
|
||||
```ts
|
||||
public async get<T>(
|
||||
url: string,
|
||||
config?: IHttpConfig,
|
||||
): Promise<AxiosResponse<IResponse<T>, any>> {
|
||||
const response = await this.axiosInstance.get<IResponse<T>>(
|
||||
url,
|
||||
config as AxiosRequestConfig,
|
||||
);
|
||||
|
||||
return response;
|
||||
}
|
||||
```
|
||||
звідси треба розуміти тільки те що `Promise<AxiosResponse<IResponse<T>, any>>` це тип, який проходить через ще один шар, що є в класі HttpService.
|
||||
```ts
|
||||
public async get<T>(url: string, config?: IHttpConfig): Promise<T> {
|
||||
return this.fetchingService
|
||||
.get<AxiosResponse<IResponse<T>, unknown>>(this.getFullApiUrl(url), {
|
||||
...config,
|
||||
headers: {
|
||||
...config?.headers,
|
||||
...this.populateContentTypeHeaderConfig(),
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
this.checkResponseStatus(result);
|
||||
return result.data as T;
|
||||
});
|
||||
}
|
||||
|
||||
// допоміжна функція для знаходження повного url
|
||||
// працює дивно коли в url є localhost, але якщо вписати в NEXT_PUBLIC_BACKEND_URL=https://inrium.org.ua/api то буде працювати бездоганно
|
||||
private getFullApiUrl(url: string): string {
|
||||
return `${this.baseUrl}/${url}`;
|
||||
}
|
||||
```
|
||||
|
||||
ось це і є та самий метод який є тут, та який тобі і вертає T напряму звідси:
|
||||
```ts
|
||||
// rpg-events - частина повної url: http[s]://[NEXT_PUBLIC_BACKEND_URL | BASE_URL]/api/rpg-events.
|
||||
const response = await this.get<IGameApiResponse[]>(`rpg-events`);
|
||||
return response
|
||||
```
|
||||
|
||||
тому response в цьому випадку має тип `IGameApiResponse[]`.
|
||||
|
||||
В загальному це виглядає так:
|
||||
|
||||
`request by hook -> http.service -> axios-client
|
||||
axios-client фетчить потрібні дані з сервака, і якщо помилок немає то передає на `const response`
|
||||
|
||||
# Не бійся задавати найпростіші та найтупіші питання, відповім на все
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user