JiSoo's Devlog

[์šฐ์•„ํ•œ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ] 7์žฅ ๋ณธ๋ฌธ

Frontend/Typescript

[์šฐ์•„ํ•œ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ] 7์žฅ

์ง€์ˆญ์ˆญ์ˆญ 2025. 6. 5. 17:19

๐Ÿ“ API ์š”์ฒญ

fetch๋กœ API ์š”์ฒญํ•˜๊ธฐ

useEffect(() => {
fetch ("https://api.baemin.corn/cart")
.then((response) => response.json())
.then(({ cartltem }) => {
setCartCount(cartitem.length);
})๏ผ›
}, [])๏ผ›

์œ„ ์ฝ”๋“œ์ฒ˜๋Ÿผ ๊ตฌํ˜„ํ•œ ์ƒํƒœ์—์„œ ์ƒˆ๋กœ์šด API ์š”์ฒญ ์ •์ฑ…์ด ์ถ”๊ฐ€๋˜๋ฉด ๊ณ„์†ํ•ด์„œ ๋น„๋™๊ธฐ ํ˜ธ์ถœ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€์ด ๋ฐœ์ƒํ•œ๋‹ค.

 

์„œ๋น„์Šค ๋ ˆ์ด์–ด๋กœ ๋ถ„๋ฆฌํ•˜๊ธฐ

์—ฌ๋Ÿฌ API ์š”์ฒญ ์ •์ฑ…์ด ์ถ”๊ฐ€๋˜์–ด ์ฝ”๋“œ๊ฐ€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋น„๋™๊ธฐ ํ˜ธ์ถœ ์ฝ”๋“œ๋Š” ์ปดํฌ๋„ŒํŠธ ์˜์—ญ์—์„œ ๋ถ„๋ฆฌ๋˜์–ด ๋‹ค๋ฅธ ์˜์—ญ(์„œ๋น„์Šค ๋ ˆ์ด์–ด)์—์„œ ์ฒ˜๋ฆฌ๋˜์–ด์•ผ ํ•œ๋‹ค.

์œ„ ์ฝ”๋“œ ๊ธฐ์ค€ fetch ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋ถ€๋ถ„์€ ์„œ๋น„์Šค ๋ ˆ์ด์–ด๋กœ ์ด๋™ํ•˜๊ณ  ์ปดํฌ๋„ŒํŠธ๋Š” ์„œ๋น„์Šค ๋ ˆ์ด์–ด์˜ ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์•„์™€ ๋ Œ๋”๋ง ํ•˜๋Š” ํ๋ฆ„์ด ๋œ๋‹ค.

ํ•˜์ง€๋งŒ ๋‹จ์ˆœํžˆ ํ•จ์ˆ˜๋ฅผ ๋ถ„๋ฆฌํ•œ๋‹ค๊ณ  ํ•ด์„œ API ์š”์ฒญ ์ •์ฑ…์ด ์ถ”๊ฐ€๋˜๋Š” ๊ฒƒ์„ ํ•ด๊ฒฐํ•˜๊ธฐ๋Š” ์–ด๋ ต๋‹ค.

 

Axios ํ™œ์šฉํ•˜๊ธฐ

fetch๋Š” ๋‚ด์žฅ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ผ ๋”ฐ๋กœ ์ž„ํฌํŠธ๋‚˜ ์„ค์น˜ํ•  ํ•„์š”๊ฐ€ ์—†์ง€๋งŒ ๋งŽ์€ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ง์ ‘ ๊ตฌํ˜„ํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

์ด๋Ÿฐ ๋ฒˆ๊ฑฐ๋กœ์›€ ๋•Œ๋ฌธ์— Axios ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.

const apiRequester๏ผš Axioslnstance = axios.create (defaultConfig);
const orderApiRequester๏ผš Axioslnstance = axios.create({
baseURL๏ผš "https๏ผš//api.baemin.or/’,
  ...defaultConfig,
});

const orderCartApiRequester๏ผš Axioslnstance = axios.create({
baseURL: "https๏ผš//cart.baemin.order/",
  ...defaultConfig,
});

 

Axios ์ธํ„ฐ์…‰ํ„ฐ ์‚ฌ์šฉํ•˜๊ธฐ

์œ„ ์ฝ”๋“œ์ฒ˜๋Ÿผ ๊ฐ requester๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ ์—ญํ• ์„ ๋‹ด๋‹นํ•˜๋Š” ์„œ๋ฒ„์ผ ๋•Œ ๊ฐ๊ฐ ๋‹ค๋ฅธ ํ—ค๋”๋ฅผ ์„ค์ •ํ•ด์ค˜์•ผ ํ•˜๋Š” ๋กœ์ง์ด ํ•„์š”ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

์ธํ„ฐ์…‰ํ„ฐ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ด requesterdp์— ๋”ฐ๋ผ ๋น„๋™๊ธฐ ํ˜ธ์ถœ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•ด ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

๋˜ํ•œ API ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ ํ•˜๋‚˜์˜ ์—๋Ÿฌ ๊ฐ์ฒด๋กœ ๋ฌถ์–ด ์ฒ˜๋ฆฌ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

apiRequester.interceptors, request .use(setRequestDefaul.tHeader);
const orderApiRequester: Axioslnstance = axios.create({
baseURL: orderApiBasellrl,
  ...defaultConfig,
});

์š”์ฒญ ์˜ต์…˜์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋นŒ๋” ํŒจํ„ด์„ ์ถ”๊ฐ€ํ•ด APIBuilder ๊ฐ™์€ ํด๋ž˜์Šค ํ˜•ํƒœ๋กœ ๊ตฌ์„ฑํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

๋นŒ๋” ํŒจํ„ด
๊ฐ์ฒด ์ƒ์„ฑ์„ ๋” ํŽธ๋ฆฌํ•˜๊ณ  ๊ฐ€๋…์„ฑ ์žˆ๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ๋””์ž์ธ ํŒจํ„ด
์ฃผ๋กœ ๋ณต์žกํ•œ ๊ฐ์ฒด์˜ ์ƒ์„ฑ์„ ๋‹จ์ˆœํ™”ํ•˜๊ณ  ๊ฐ์ฒด ์ƒ์„ฑ ๊ณผ์ •์„ ๋ถ„๋ฆฌํ•ด ๊ฐ์ฒด๋ฅผ ์กฐ๋ฆฝํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•œ๋‹ค.

 

APIBuilder ํด๋ž˜์Šค๋Š” ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ์ฝ”๋“œ๊ฐ€ ๋งŽ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์ง€๋งŒ ์˜ต์…˜์ด ๋‹ค์–‘ํ•œ ๊ฒฝ์šฐ์— ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ์„ค์ •๊ฐ’์— ๋”ฐ๋ผ ์ ์šฉํ•˜๊ณ  ํ•„์š” ์—†๋Š” ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ์„ ํƒ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ๋„ ์žˆ๋‹ค.

 

๐Ÿ‘‰๐Ÿป ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ์ฝ”๋“œ

์–ด๋–ค ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ๋•Œ ๋ฐ˜๋ณต์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋ณธ์ ์ธ ์ฝ”๋“œ

 

API ์‘๋‹ต ํƒ€์ž… ์ง€์ •ํ•˜๊ธฐ

interface Response<T> {
data๏ผš T;
status: string;
serverDateTime๏ผš string;
errorCode?: string; // FAIL, ERROR
errorMessage?๏ผš string; // FAIL, ERROR
}

๊ฐ™์€ ์„œ๋ฒ„์—์„œ ์˜ค๋Š” ์‘๋‹ต ํ˜•ํƒœ๋Š” ๋Œ€์ฒด๋กœ ํ†ต์ผ๋˜์–ด ์žˆ์–ด ํ•˜๋‚˜์˜ Response ํƒ€์ด์œผ๋กœ ๋ฌถ์ผ ์ˆ˜ ์žˆ๋‹ค.

 

๋ทฐ ๋ชจ๋ธ ์‚ฌ์šฉํ•˜๊ธฐ

API ์‘๋‹ต์€ ๋ณ€ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ํฌ๋‹ค.

์ƒˆ ํ”„๋กœ์ ํŠธ๋Š” ์„œ๋ฒ„ ์ŠคํŽ™์ด ์ž์ฃผ ๋ฐ”๋€Œ๊ธฐ ๋•Œ๋ฌธ์— ๋ทฐ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•ด API ๋ณ€๊ฒฝ์— ๋”ฐ๋ฅธ ๋ฒ”์œ„๋ฅผ ํ•œ์ •ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

๋ทฐ ๋ชจ๋ธ์„ ๋งŒ๋“ค๋ฉด API ์‘๋‹ต์ด ๋ฐ”๋€Œ์–ด๋„ UI๊ฐ€ ๊นจ์ง€์ง€ ์•Š๊ฒŒ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋‹ค.

 

Superstruct ์‚ฌ์šฉํ•ด ๋Ÿฐํƒ€์ž„์—์„œ ์‘๋‹ต ํƒ€์ž… ๊ฒ€์ฆ

๋Ÿฐํƒ€์ž„ ์‘๋‹ต ํƒ€์ž… ๊ฒ€์ฆ์„ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” Superstruct ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š”

- Superstruct๋ฅผ ์‚ฌ์šฉํ•ด ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜์™€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฐ์ดํ„ฐ์˜ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

- Superstruct๋Š” ๋Ÿฐํƒ€์ž„์—์„œ์˜ ๋ฐ์ดํ„ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ†ตํ•ด ๊ฐœ๋ฐœ์ž์™€ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ž์„ธํ•œ ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ๋ฅผ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด ๊ณ ์•ˆ๋˜์—ˆ๋‹ค.

import { assert, is, validate, object, number, string, array } from "superstruct";

const Article = object({
id: number(),
title: stringO,
tags: array(stringO),
author: object({
id: number(),
}),
});

const data = {
id: 34,
title: "Hello World",
tags: ["news", "features"],
author: {
id: 1,
},
};

assert(data, Article);
is(data, Article);
validate(data, Article);

Article ๋ณ€์ˆ˜๋Š” Superstruct์˜ object() ๋ชจ๋“ˆ์˜ ๋ฐ˜ํ™˜ ๊ฒฐ๊ณผ๋‹ค.

Article์˜ id๋Š” ์ˆซ์ž, title์€ ๋ฌธ์ž์—ด ๋“ฑ ์ด๋Ÿฐ ์†์„ฑ์„ ๊ฐ€์ง„ ๊ฐ์ฒด ํ˜•ํƒœ์˜ object์ด๋‹ค.

assert: ์œ ํšจํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ์—๋Ÿฌ ๋˜์ง„๋‹ค.

is: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ๊ฒฐ๊ณผ์— ๋”ฐ๋ผ true๋‚˜ false๊ฐ’ ๋ฐ˜ํ™˜

validate: [error, data] ํ˜•์‹์˜ ํŠœํ”Œ ๋ฐ˜ํ™˜, ์œ ํšจํ•˜์ง€ ์•Š์„ ๋•Œ๋Š” ์—๋Ÿฌ ๊ฐ’ ๋ฐ˜ํ™˜, ์œ ํšจํ•˜๋ฉด ์ฒซ ๋ฒˆ์งธ ์š”์†Œ๋กœ undefined, ๋‘ ๋ฒˆ์งธ ์š”์†Œ๋กœ data value ๋ฐ˜ํ™˜

 

 

๐ŸŽˆ API ์ƒํƒœ ๊ด€๋ฆฌํ•˜๊ธฐ

์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ํ˜ธ์ถœํ•˜๊ธฐ

์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋“ค์€ ์„œ๋น„์Šค ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ๋น„๋™๊ธฐ ์ƒํƒœ๋ฅผ ๋ณ€ํ™”์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

์ปดํฌ๋„ŒํŠธ๋Š” ์ด๋Ÿฐ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์ƒํƒœ๋ฅผ ๊ตฌ๋…ํ•˜๋ฉฐ ์ƒํƒœ๊ฐ€ ๋ฐ”๋€” ๋•Œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.

 

Redux๋Š” ๋น„๋™๊ธฐ ์ƒํƒœ๊ฐ€ ์•„๋‹Œ ์ „์—ญ ์ƒํƒœ๋ฅผ ์œ„ํ•ด ๋งŒ๋“ค์–ด์ง„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ผ ๋ฏธ๋“ค์›จ์–ด๋กœ ๋ถˆ๋ฆฌ๋Š” ์—ฌ๋Ÿฌ ๋„๊ตฌ๋ฅผ ๋„์ž…ํ•ด ๋น„๋™๊ธฐ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค.

๊ทธ๋ž˜์„œ ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ์ฝ”๋“œ๊ฐ€ ๋งŽ์•„์ง€๋Š” ๋“ฑ ๊ฐ„ํŽธํ•˜๊ฒŒ ๋น„๋™๊ธฐ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์–ด๋ ต๋‹ค.

 

MobX ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ๋Š” ์ด๋Ÿฐ ๋ถˆํŽธํ•จ์„ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ๋น„๋™๊ธฐ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๋ถ„๋ฆฌํ•ด ์•ก์…˜์œผ๋กœ ๋งŒ๋“ค๊ฑฐ๋‚˜ runInAction ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ์ƒํƒœ ๋ณ€๊ฒฝ์„ ์ฒ˜๋ฆฌํ•œ๋‹ค.

 

ํ›…์œผ๋กœ ํ˜ธ์ถœํ•˜๊ธฐ

ํ›…์„ ์‚ฌ์šฉํ•œ ๋ฐฉ๋ฒ•์€ ์ƒํƒœ ๋ณ€๊ฒฝ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•œ ๋ฐฉ์‹๋ณด๋‹ค ํ›จ์”ฌ ๊ฐ„๋‹จํ•˜๋‹ค.

ํ›…์€ ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•ด ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๋ฐœ์ƒํ•œ ์˜๋„์น˜ ์•Š์€ ์ƒํƒœ ๋ณ€๊ฒฝ์„ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋œ๋‹ค.

 

 

๐Ÿ”ซ  API ์—๋Ÿฌ ํ•ธ๋“ค๋ง

ํƒ€์ž… ๊ฐ€๋“œ ํ™œ์šฉํ•˜๊ธฐ

Axios ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ๋Š” Axios ์—๋Ÿฌ์— ๋Œ€ํ•œ isAxiosError ํƒ€์ž… ๊ฐ€๋“œ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์žˆ๋‹ค.

interface ErrorResponse {
  status: string;
  serverDateTime: string;
  errorCode: string;
  errorMessage: string;
}

*์‚ฌ์šฉ์ž ์ •์˜ ํƒ€์ž… ๊ฐ€๋“œ ์ž‘์„ฑ ์‹œ ํƒ€์ž… ๊ฐ€๋“œ ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์œผ๋กœ parameterName is Type ํ˜•ํƒœ์˜ ํƒ€์ž… ๋ช…์ œ๋ฅผ ์ •์˜ํ•ด ์ฃผ๋Š” ๊ฒŒ ์ข‹๋‹ค.

 

์—๋Ÿฌ ์„œ๋ธŒํด๋ž˜์‹ฑํ•˜๊ธฐ

์‹ค์ œ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ๋•Œ ๋‹จ์ˆœ ์„œ๋ฒ„ ์—๋Ÿฌ๋งŒ์ด ์•„๋‹ˆ๋ผ ์ธ์ฆ ์ •๋ณด ์—๋Ÿฌ, ๋„คํŠธ์›Œํฌ ์—๋Ÿฌ ๋“ฑ ๋‹ค์–‘ํ•œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

์ด๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด ์„œ๋ธŒํด๋ž˜์‹ฑ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๐Ÿ‘‰๐Ÿป ์„œ๋ธŒํด๋ž˜์‹ฑ

๊ธฐ์กด ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•ด ์ƒˆ๋กœ์šด ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๊ณผ์ •

 

์„œ๋ธŒํด๋ž˜์‹ฑ์„ ํ™œ์šฉํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์ฝ”๋“œ์‚ฌ์—์„œ ์–ด๋–ค ์—๋Ÿฌ์ธ์ง€ ๋ฐ”๋กœ ํ™•์ธ ๊ฐ€๋Šฅํ•˜๋‹ค.

๋˜ํ•œ ์—๋Ÿฌ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ฌด์—‡์ธ์ง€์— ๋”ฐ๋ผ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์„ ๋‹ค๋ฅด๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ํ™œ์šฉํ•œ ์—๋Ÿฌ ์ฒ˜๋ฆฌ

Axios ๊ฐ™์€ ํŽ˜์นญ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ธํ„ฐ์…‰ํ„ฐ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. ์ด๊ฑธ ์‚ฌ์šฉํ•˜๋ฉด HTTP ์—๋Ÿฌ์— ์ผ๊ด€๋œ ๋กœ์ง์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์—๋Ÿฌ ๋ฐ”์šด๋”๋ฆฌ๋ฅผ ํ™œ์šฉํ•œ ์—๋Ÿฌ ์ฒ˜๋ฆฌ

์—๋Ÿฌ ๋ฐ”์šด๋”๋ฆฌ๋Š” ์—๋Ÿฌ ๋ฐœ์ƒํ•  ๋•Œ ๊ณตํ†ต์œผ๋กœ ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๋‹ค.

์—๋Ÿฌ ๋ฐ”์šด๋”๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ ํ•˜์œ„์— ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๋ฅผ ์บ์น˜ํ•˜๊ณ  ํ•ด๋‹น ์—๋Ÿฌ๋ฅผ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋ถ€๋ชจ ์—๋Ÿฌ ๋ฐ”์šด๋”๋ฆฌ์—์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.

์—๋Ÿฌ ๋ฐ”์šด๋”๋ฆฌ๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ์ปดํฌ๋„ŒํŠธ ๋Œ€์‹  ์—๋Ÿฌ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ฑฐ๋‚˜ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์—๋Ÿฌ๋ฅผ ๊ณตํ†ต ์ฒ˜๋ฆฌํ•  ๋•Œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

 

โš’๏ธ  API ๋ชจํ‚น

๋ชจํ‚น์€ ๊ฐ€์งœ ๋ชจ๋“ˆ์„ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.

์„œ๋ฒ„๊ฐ€ ๋ถˆ์•ˆ์ •ํ•˜๊ฑฐ๋‚˜ AWS ๋“ฑ์— ๋ฌธ์ œ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์„œ๋ฒ„์˜ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๊ณ  ํ”„๋ก ํŠธ ๊ฐœ๋ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

JSON ํŒŒ์ผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

๊ฐ„๋‹จํ•œ ์กฐํšŒ๋งŒ ํ•„์š”ํ•˜๋ฉด *.json ํŒŒ์ผ ๋งŒ๋“ค๊ฑฐ๋‚˜ ํŒŒ์ผ ์•ˆ์— JSON ํ˜•์‹์˜ ์ •๋ณด๋ฅผ ์ €์žฅํ•ด export ํ•ด์ฃผ๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

์ด ๋ฐฉ๋ฒ•์€ ๋ณ„๋„๋กœ ์„ค์ •๋„ ํ•„์š” ์—†์–ด์„œ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•˜๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ API URL๋กœ ์š”์ฒญํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ์„œ ์ถ”ํ›„์— ์š”์ฒญ ๊ฒฝ๋กœ๋ฅผ ๋ฐ”๊ฟ”์•ผ ํ•œ๋‹ค.

 

NextApiHandler ํ™œ์šฉํ•˜๊ธฐ

ํ”„๋กœ์ ํŠธ์—์„œ Next.js ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด NextApiHandler๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

NextApiHandler๋Š” ํ•œ ํŒŒ์ผ ์•ˆ์— ํ•˜๋‚˜์˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋””ํดํŠธ ์ต์ŠคํฌํŠธ๋กœ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋ฉฐ ํŒŒ์ผ ๊ฒฝ๋กœ๊ฐ€ ์š”์ฒญ ๊ฒฝ๋กœ๊ฐ€ ๋œ๋‹ค.

์‘๋‹ตํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฐ’ ์ •์˜ ํ›„ ํ•ธ๋“ค๋Ÿฌ ์•ˆ์—์„œ ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต์„ ์ •์˜ํ•˜๋ฉด ๋œ๋‹ค.

ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋‹จ์ˆœ ํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฒƒ๊ณผ ๋‹ค๋ฅด๊ฒŒ ์ค‘๊ฐ„ ๊ณผ์ •์— ์‘๋‹ต ์ฒ˜๋ฆฌ ๋กœ์ง์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

import { NextApiHandler } from "next";

const BRANDS๏ผš Brand[] = [
  {
    id๏ผš 1,
    label๏ผš "๋ฐฐ๋ฏผ์Šคํ† ์–ด’,,
  },
  {
    id๏ผš 2,
    label๏ผš ”๋น„๋งˆํŠธ’,,
  },
];

const handler: NextApiHandler = (req, res) => {
  // request ์œ ํšจ์„ฑ ๊ฒ€์ฆ
  
  res.json(BRANDS);
};

export default handler;

 

API ์š”์ฒญ ํ•ธ๋“ค๋Ÿฌ์— ๋ถ„๊ธฐ ์ถ”๊ฐ€ํ•˜๊ธฐ

API ์š”์ฒญ์„ ํ›…์ด๋‚˜ ๋ณ„๋„ ํ•จ์ˆ˜๋กœ ์„ ์–ธํ•˜๊ณ  ์กฐ๊ฑด์— ๋”ฐ๋ผ ๋ชฉ์—… ํ•จ์ˆ˜๋ฅผ ๋‚ด๋ณด๋‚ด๊ฑฐ๋‚˜ ์‹ค์ œ ์š”์ฒญ ํ•จ์ˆ˜๋ฅผ ๋‚ด๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐœ๋ฐœ์ด ์™„๋ฃŒ๋œ ํ›„์—๋„ ์œ ์ง€๋ณด์ˆ˜ํ•  ๋•Œ ๋ชฉ์—… ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์‹ค์ œ API์— ์š”์ฒญ ๋ณด๋‚ด๊ณ  ํ‰์†Œ์—๋Š” ์„œ๋ฒ„์— ์˜์กดํ•˜์ง€ ์•Š๊ณ  ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋‹ค.

 

axios-mock-adapter๋กœ ๋ชจํ‚นํ•˜๊ธฐ

axios-mock-adapter๋Š” Axios ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ„์„œ ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต ๊ฐ’์„ ๋Œ€์‹  ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๋‹จ์ˆœ ์‘๋‹ต ๋ฐ”๋””๋งŒ ๋ชจํ‚นํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ƒํƒœ ์ฝ”๋“œ, ์‘๋‹ต ์ง€์—ฐ ์‹œ๊ฐ„ ๋“ฑ์„ ์ถ”๊ฐ€๋กœ ์„ค์ • ๊ฐ€๋Šฅํ•˜๋‹ค.

GET๋ฟ๋งŒ ์•„๋‹ˆ๋ผ POST, PUT ๋“ฑ ๋‹ค๋ฅธ ์š”์ฒญ์— ๋Œ€ํ•œ ๋ชฉ์—…์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๋ชฉ์—… ์‚ฌ์šฉ ์—ฌ๋ถ€ ์ œ์–ดํ•˜๊ธฐ

๋กœ์ปฌ์—์„œ๋Š” ๋ชฉ์—…์„ ์‚ฌ์šฉํ•˜๊ณ  dev๋‚˜ ์šด์˜ ํ™˜๊ฒฝ์—์„œ๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ ค๋ฉด ํ”Œ๋ž˜๊ทธ๋ฅผ ์‚ฌ์šฉํ•ด ๋ชฉ์—…์„ ๊ฐœ๋ฐœํ•  ๋•Œ์™€ ๊ฐœ๋ฐœํ•˜์ง€ ์•Š์„ ๋•Œ๋ฅผ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

const useMock = Object.is(REACT_APP_MOCK, "true");

const mockFn = ({ status = 200, time = 100, use = true }๏ผš MockResult) => use &&
  mock.onGet(A/orderVlist/).reply (() =>
    new Promise((resolve) =>
      setTimeout(() => {
        resolve([
          status,
            status === 200 ? fetchOrderListSuccessResponse : undefined,
        ]);
      }, time)
    )
  );
  
if (useMock) {
  mockFn({ status: 200, time: 100, use: true });
}

ํ”Œ๋ž˜๊ทธ์— ๋”ฐ๋ผ mockFn์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋„˜๊ฒจ ํŠน์ • mock ํ•จ์ˆ˜๋งŒ ๋™์ž‘ํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

axios-mock-adapter๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” API ์š”์ฒญ์„ ์ค‘๊ฐ„์— ๊ฐ€๋กœ์ฑ„๋Š” ๊ฑฐ๋ผ ์‹ค์ œ๋กœ API ์š”์ฒญ์„ ์ฃผ๊ณ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค.

๋”ฐ๋ผ์„œ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์˜ ๋„คํŠธ์›Œํฌ ํƒญ์—์„œ๋Š” ํ™•์ธํ•˜๊ธฐ ์–ด๋ ต๋‹ค.

์ด ์š”์ฒญ์˜ ํ๋ฆ„์„ ํŒŒ์•…ํ•˜๋ ค๋ฉด react-query-devtools๋‚˜ redux test tool ๊ฐ™์€ ๋ณ„๋„ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

๋ชฉ์—…์„ ์‚ฌ์šฉํ•  ๋•Œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ํ™•์ธํ•˜๊ณ  ์‹ถ์„ ๋•Œ๋Š” ๋„คํŠธ์›Œํฌ์— ๋ณด๋‚ธ ์š”์ฒญ์„ ๋ณ€๊ฒฝํ•ด ์ฃผ๋Š” Cypress ๊ฐ™์€ ๋„๊ตฌ์˜ ์›นํ›…์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

 

728x90