api request-ების ორგანიზირება

პრობლემა

თუ ჩვენი აპლიაკცია ზომაშI პატარაა არანაირი პრობლემა არ იქნება რომ ჩვენ ყველა api request რომ ეგრევე inline ვწეროთ და ყველა ჯერზე როცა ეს რექუესტი დაგვჭირდება ახლიდნ ვადგინოთ ეს სტრინგი, მაგრამ ცოტა მოზრდილ აპლიაკცებIშ ეს უკვე პრობლემა გახდება.

ჩვენ გვექნება api route-ები რომელიც თითქმის ყველა გვერდზე შეიძლება დაგვჭირდეს და შეცდომის დაშვება ასეთ ქეისებში საკმაოდ ადვილი იქნება.

api გზიზს არასწორად გაწერის პრობლემას თუ დავივიწყებთ შემდეგი პრობლემა ის არის რომ შეიძლება აპლიაკცაიში დაგვჭიდეს გაგზავნამდე რაღაცა ინფორმაციის შემომწება ან მიბმა ყველა რაუტზე, მაგალითად გვინდა რომ auth token მივაბათ ყველა რექუესტს ეს ჩვენ მაშინ ყველგან უნდა ვქნათ სადაც ვიყენებთ api-ს და გამორჩენის რისკი აქაც საკმაოდ დიდია

სერვისები

ზემოდ ხსენებული პრობლემის მოგვარება არის შესაძლებელი სერვისებით. იდეა არის რომ ყველა api route-ისთვის დავწერთ ფუნქციას რომელიც ამ რაუტზე აგზავნის ინფორმაციას, ასეთ შემთხვევაში ჩვენ როცა მოგვინდება რომ მომხმარებლის ინფორმაცია წამოვიღოთ სულ ერთ ადგილს გავივლით და სულ დარწმუნებული ვიქნებით რომ სწორ api-ზე ვაგზავნით მოთხოვნას და შეცდომის რისკი საკმაოდ მცირდება.

მაგრამ ამ ქეისშიც შეიძლება მოგვიოს ხოლმე სრული api url-ის გაწერა რაც ასევე შეიძლება შეგვეშლოს, ნუ რათქმაუნდა შეგვიძლია რომ api ცალკე ცვალდში გავიტანოთ და სულ ეგ საწყისი წერტილი გამოვიყოთ მაგრამ ესეც შეიძლება დაგავივწყდეს, ბევრად აჯობებს თუ რაიმე ერთი ობექტი გვექნება ინფორმაციის მოსათხვოად.

ამისთვის ჩვენ შეგვიძლია გამოვიყენოთ axios instance-ები სადაც მარტო ერთ ადგილზე გავწერთ api-ს სრულ გზას, საჭირო ჰედერებს და სხვა ინმფორმაციას და ყველა ჯერზე უბრალოდ ამ ინსტანციას გამოვიყენებთ იმის მაგივრად რომ ახლიდან ვწეროთ ყველაფერი.

იმპლემტაციის დეტალები

აპლიაკციის რუტში უნდა შევქმნათ საქაღლდე services მაგის შიგნით უდნა შევქმნათ ფაილი axios.{ts,js} სადაც დავწერთ ამდაგვარ რაღაცას.

import axios from 'axios';

const instance = axios.create({
  baseURL: https://my-amazing-backend.com/api/,
  headers: {
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
});

export default instance;

მერე კერძო api request-ისთვის ფუნქციის შექმნისთვის უნდა გავაკეთოთ ახალი ფაილი /services საქაღალდეში და დავარქვათ ნებისმენერი სახელი, უნდა ვეცადოთ რომ ლოგიკრაუდ დავყოთ ეს ფაილები, ავტორიზაციის რექუესტები ცალკე, ბლოგების წამოყღება ცალკე და ასე შემდეგ.

ამ მაგალითისთვის შევქმნი საქაღალდეს submissions.ts და შიგნით ასეთ რაღაცას ჩავწერ

import { AxiosResponse } from 'axios';
import { Submission } from "types"

export const getSubmissionsRequest = async (token: string, page: number, problemId): Promise<AxiosResponse<Submission[]>> => {
  return await axios.get('/submissions', {
    headers: {
      Authorization: `Bearer ${token}`,
    },
    params: {
      page,
      problemId,
    },
  });
};

და შემდეგ ჩვენ როცა დაგვჭირდება submission-ების წამოღება შეგვიძლია რომ სულ ეს ფუნქცია გამოვიყენოთ, ამის ბონუსი ის არის რომ გზა არ შეგვეშლებას, ts-ს საშUლებით დეკლარლებული იქნება თუ ზუსტად რა პარამეტრები ჭირდება ამ api-ს რომ იმუშოს და შეცდომის შესაძლებლობა საკმაოდ იწევს.

გამოყენების წესები/რჩევები

  • სერვისი აუცუკლებლად უნდა იყოს camelCase-ში.

  • სერვისიდან დააბრუნეთ ხოლმე მთლაინი რექუესტი, არ დააბრუნოთ მხოლოდ data, შესაძლებელია რომ სტატუსი დაგჭირდეთ ხოლმე მომავალში, ან მესიჯი და თუ რაიმე ძვირი

  • თუ იყენებთ ts-ის ან jsdoc-ს აუცულებალად გააკეთეთ ტიპერება დაბრუნების ტიპის და პარამეტრების, any-ს გამოიყნება არ არის მიზან შეწონილი, რადგანაც ამ შემთხვევაში სერვისების ერთერთი უდიდესი ბონუსი იკარგება

  • როცა აქსიოს ვიყენებთ ქუერი პარამეტრები არ გადავცეთ ეგრევე სტრინგიად რაუტში (მაგ submissions/?page=1&problemId) და გადაეცით მეორე პარამეტრად კონფიგურაციაში params ობიექტში, ამის მიზეზი ის არის რომ ჯერ ერთი მახინჯია ასე დაწერე და მეორეც ერთი იმის გამო რომ აქსიოსი თქვენ მიერ მიწოდებულ გზაზს url-ად დაპარსავს და მოაშორებს +, whitespace, და სხვა ნიშნებს რომელებიც რაუტში არ შეიძლება, ამის გამო არასწორი ინფორმაცია გაიგზავნება და დამაბნეველი ბაგი გექნებათ

  • დაყავით სერვისები ცალ ცალკე ფაილებშI ერთად არ გქონდეთ.

  • დაყოფის მერეც ერთ ობიექწტში არ ჩადოთ სერვსები კომფორტისთვის და დაჯგუფებისთვის, ეს არ არის კარგი იდეა tree shaking-ის გამო, შეიძლება დიდი ფაილები არ იყოს მაგრამ მაინც არ ღირს ერთ ობიექტში ფაილის სერვისების ჩადება, ჯობია ლოგიკურად ფაილების მიხედვით დაიყოს

Last updated