commit 3299f9e467ba97b59249ee4980879066c4f4c187 Author: Rhinemann Date: Fri Jul 4 14:39:46 2025 +0300 Upload files to "/" diff --git a/Невеличкий гайд по http сервісу та requestʼах.md b/Невеличкий гайд по http сервісу та requestʼах.md new file mode 100644 index 0000000..3bf04dd --- /dev/null +++ b/Невеличкий гайд по http сервісу та requestʼах.md @@ -0,0 +1,125 @@ +### Пару важливих речей: +- Метод = функція +- Класс != тип - в TS є такі штуки як `AxiosResponse, 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(`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( + url: string, + config?: IHttpConfig, + ): Promise, any>> { + const response = await this.axiosInstance.get>( + url, + config as AxiosRequestConfig, + ); + + return response; + } +``` +звідси треба розуміти тільки те що `Promise, any>>` це тип, який проходить через ще один шар, що є в класі HttpService. +```ts + public async get(url: string, config?: IHttpConfig): Promise { + return this.fetchingService + .get, 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(`rpg-events`); +return response +``` + +тому response в цьому випадку має тип `IGameApiResponse[]`. + +В загальному це виглядає так: + +`request by hook -> http.service -> axios-client +axios-client фетчить потрібні дані з сервака, і якщо помилок немає то передає на `const response` + +# Не бійся задавати найпростіші та найтупіші питання, відповім на все + +