비동기 함수 클래스로 간편하게 인스턴스화 하기!

렐루·2024년 6월 19일
1

리액트

목록 보기
18/20

1. 들어가며

맨처음 딥다이브로 혼자서 클래스 공부할 때 이해가 잘 안될 뿐더러 정말 정말 이런거 왜 배우나 싶었던 기억이 있습니다.
꾹 참고 어거지로 읽어놓은 것이 이제야 도움이 되네요 ㅎㅎㅎ

튜터님께 axios를 배우면서 class 문법을 통해 효율적이고 편리한 코드를 작성하는 방법까지 함께 배웠습니다.
axios도 이전까지 그냥 인터셉트 정도? 뭐 인스턴스화 한다고 하는데 그게 그렇게 편리할 정도인가 하면서 fetch 써왔지만 팀플을 하게 되고 플젝 규모가 커지다보니 api 인스턴스 하나 임포트해서 자동완성하며 직관적인 이름으로 가져다 쓰게 되니 정말정말 강력하고 편하다는 것을 깨닫게 되었습니다.



2. axios를 클래스로!

2-1. 기본 코드

import axios from "axios";

const BASE_URL = "https://api.~~.com";

class API {
  #baseUrl = BASE_URL;
  #client;

  constructor() {
    this.#client = axios.create({ baseURL: this.#baseUrl });
  }
}

const api = new API();

export default api;

위의 코드는 기본 시작이 됩니다.
axios는 baseURL을 설정할 수 있어서 상수로 설정을 하고 초기설정을 해줌으로서 일괄적인 관리와 캡슐화를 편리하게 할 수 있습니다.

나중에 위의 클래스를 이용해서 함수에 접근하게 되면 api를 임포트 하여 인스턴스의 메서드들을 편리하게 꺼내 쓸 수 있게 됩니다!!



2-2. 추가하기

class API {
  #baseUrl = BASE_URL;
  #client;

  brands;
  products;
  constructor() {
    this.#client = axios.create({ baseURL: this.#baseUrl });
    this.products = new ProductsAPI(this.#client);
  }
}

// 아래는 추가하고 싶은 함수 클래스
class ProductsAPI {
  #client;
  constructor(client) {
    this.#client = client;
  }
  async getProducts() {
    const response = await this.#client.get("/products");
    const data = response.data;
    const result = data.result;
    return result;
  }
}

export default ProductsAPI;

위의 코드와 같이 다른 파일을 생성해서 저희가 최초에 생성한 기본 axios의 설정들을 먹고 시작해야 하니까 기본 클래스 내부에서 설정한 axios를 넘겨주고 인스턴스의 프로퍼티로 쉽게 접근할 수 있게 하면 됩니다!!



2-3. 사용 방법


위와 같이 자동추천 기능을 통해서 최초의 api만 import 하게 되면 이후에는 제가 보면서 고를 수 있으니까 전혀 이름 외울 필요도 없고
만약에 함수에 문제가 생겨도 클래스 지정 파일에서만 수정하면 되니까 정말 안쓸 이유가 없습니다!



3. api를 클래스로!

3-1. 기본 코드

아래의 코드 예시는 supebase 코드 예시입니다만
tmdb나 firebase 등등 다 비슷해서 적용 가능할 것 같네요!!

// 수퍼베이스 컨피그 파일!
import { createClient } from '@supabase/supabase-js';
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
const supabaseKey = import.meta.env.VITE_SUPABASE_KEY;

const supabase = createClient(supabaseUrl, supabaseKey);
export default supabase;

// 기본 코드가 되는 파일
import supabase from '../../supabase/supabase';
import AlcoholApi from './alcohol.api';
import DessertApi from './dessert.api';
import FoodApi from './food.api';

class API {
  #supabase;
  constructor(supabaseClient) {
    this.#supabase = supabaseClient;
    this.food = new FoodApi(this.#supabase);
    this.dessert = new DessertApi(this.#supabase);
    this.alcohol = new AlcoholApi(this.#supabase);
  }
}

export const supabaseApi = new API(supabase);

위의 코드를 보면 엑시오스와 아주 똑같습니다.
결국 인스턴스로 내려주기 전에 가장 공통이 되는 부분이 어디일까 고민하고 해당 부분을 중심으로 가지치기 해준다는 느낌을 저는 받았습니다!

수퍼베이스같이 이미 만들어진 api는 기본 키랑 url을 받아서 제공된 방법으로 접근가능하게 만들어놨기 때문에 굳이 axios를 사용하지 않고 createClient로 생성해서 해당 값을 기본값으로 내려주게 만들었습니다.



3-2. 추가하기

export const FOOD_TABLE_NAME = 'food';
export const MEAL_TIME = 'meal_time';
export const CUISINE_TYPE = 'cuisine_type';
export const COMPANY = 'company';

class FoodApi {
  #supabase;
  #food;
  constructor(supabaseClient) {
    this.#supabase = supabaseClient;
    this.#food = this.#supabase.from(FOOD_TABLE_NAME);
  }
  async getAllFoods() {
    const { data, error } = await this.#food.select();
    if (error) {
      throw new Error(error.message);
    }
    return data;
  }
  async getFoods(queryObj) {
    const { data, error } = await this.#food
      .select()
      .contains(MEAL_TIME, [queryObj[MEAL_TIME]])
      .eq(CUISINE_TYPE, queryObj[CUISINE_TYPE])
      .contains(COMPANY, [queryObj[COMPANY]]);
    if (error) {
      throw new Error(error.message);
    }
    return data;
  }
}

export default FoodApi;

위의 코드를 보시면 supabaseClient를 통해서 기본 config가 된 함수를 받고 해당 함수를 수퍼베이스에서 제공하는 메서드들로 공통된 부분을 묶는 작업들입니다.

FoodApi는 다양한 db 테이블 중에서 food만 선택하고 싶어서 출발을 this.#food = this.#supabase.from(FOOD_TABLE_NAME); 다음과 같이 해서 내려주면 아래 인스턴스 메서드들은 해당 값에서 출발해서 편하게 쓸 수 있게 됩니다.



3-3. 사용하기


위의 사진을 통해 사용되는 모습을 확인하실 수 있습니다.
엑시오스와 같이 그냥 최초의 인스턴스 import만 하면 이후로는 계속 체이닝으로 타고 들어가서 고를 수 있습니다.



4. 마치며

엑시오스나 클래스 같은 강력한 도구들을 혼자 사용할 때 전혀 그 위력을 체감하지 못했다는 점에서 제 한계가 여실히 드러나는 것 같아 참 마음이 아프고 답답했습니다.. ㅠㅜ
하지만 좋은 튜터님들과 학습 동료들을 만나 그래도 이제는 조금 알게되어 감사했습니다. 또 앞으로의 기술의 선택이나 학습의 방향에 대해서 생각해볼 수 있었습니다.

긴글 읽어 주셔서 감사합니다.

profile
프론트 공부중입니다!

0개의 댓글