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