1회차 챌린지 주제 : 좋은 모듈 설계와 객체지향
Service, http모듈, cookie 모듈 등의 기능을 논리적으로 분리하고 설정하는 것이 핵심이다.
실무에서는 대부분 외부 의존성을 그대로 사용하지 않고 내부에서 새롭게 정의한 인터페이스를 사용한다.
외부 변경으로 인한 영향을 최소화 할 수 있다는 장점이 있다.
이때 큰 비용을 들이지 않고 적용할 수 있도록 간결한 인터페이스를 구현하는 것이 핵심이다.
리팩토링 할 AuthService는 인증 관련 비즈니스 로직들을 다루는 모듈이다. 리팩토링을 하면서 이후에 재사용성, 확장성을 고려하여 하나의 부모클래스를 extend하는 방법으로 모듈을 설계하는 미션에 어떻게 설계를 해야할지 고민을 하였다.
또한, 하나의 모듈 (= 파일, 클래스, 메소드, 변수)이 하나의 역할만 수행하도록 설계하는 고민을 하였다.
http 통신 기능을 분리해주었다. 다만 추후에 보완을 한다면, Service가 하는 일은 API 요청 전송 외에도 많을텐데, 각각의 auth.service.ts
user.service.ts
가 Service를 extend하고 있는 점이 어색한 점이 다분하여 axios 기능을 추상화할 방법을 좀 더 찾아보아야겠다.
import axios from 'axios';
import { AxiosOptions } from '../types/http';
export default class Service {
async axios(options: AxiosOptions) {
const { data } = await axios({
baseURL: process.env.NEXT_PUBLIC_API_HOST,
...options,
});
return data;
}
}
import cookies from 'js-cookie';
type TokenType = 'access' | 'refresh';
class TokenProvider {
static get(tokenType: TokenType) {
return cookies.get(tokenType);
}
static set(tokenType: TokenType, token: string, expires: number) {
cookies.set(tokenType + 'Token', token, { expires });
}
static hasExist(tokenType: TokenType) {
return !!cookies.get(tokenType);
}
static clear() {
cookies.remove('accessToken');
cookies.remove('refreshToken');
}
}
export default TokenProvider;
useRequset hook을 통해 react-query의 useQuery를 격리하였다.
import { useQuery } from 'react-query';
type Options = {
refetchInterval?: number;
};
export const useRequest = (request: () => {}, options?: Options) =>
useQuery(request.name, request, { ...options });
객제지향과 상속에 대한 이론적으로 공부했었던 원리를 내가 직접 class를 설계하는 과정에서 유의미한 부분을 찾아 추상화할지에 대한 고민을 하는 과정에서 객체지향을 몸소 느낄 수 있었다.
axios를 확장성있게 구현하는 과정에서 axios 인스턴스 만들기, 요청 config, 응답 스키마, 인터셉터 등 다양한 기능들을 사용하는 데에 한계가 있었다. 이 기능들을 어떻게 활용할 수 있을지에 대한 부분도 고민을 해보아야겠다.