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