๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ“‚ ์‚ฝ์งˆ ๋…ธํŠธ/์—๋Ÿฌ ํ•ด๊ฒฐ

Proxy ์„ค์ • ์‹œ ์„œ๋ฒ„๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์˜ฌ๋ฐ”๋ฅธ ์—”๋“œํฌ์ธํŠธ๋กœ API๋ฅผ ์š”์ฒญํ•˜์ž

by Dev. Ella 2023. 6. 11.

๐Ÿค”  ์˜ค๋Š˜์˜ ์—๋Ÿฌ

React Proxy ์„ค์ • ์ค‘, ์˜ค๋Š˜์€ ์•„๋ž˜์™€ ๊ฐ™์ด ๋‘ ์—๋Ÿฌ๋ฅผ ๋งŒ๋‚ฌ๋‹ค.

GET http://localhost:3001/api/todos 404 (Not Found)
Uncaught (in promise) SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON

 

 

๐Ÿง ์ฒ˜์Œ ์ž‘์„ฑํ•œ ์ฝ”๋“œ

๋ ˆํฌ์ง€ํ† ๋ฆฌ ์•ˆ์—๋Š” Bookservice๋ฅผ ์ œ๊ณตํ•˜๋Š” api ํด๋”์™€ Todoservice๋ฅผ ์ œ๊ณตํ•˜๋Š” api2๋ผ๋Š” ๋‘ ํด๋”๊ฐ€ ์žˆ๋‹ค. ์‹ค์ œ๋กœ ํ”„๋กœ์ ํŠธ ๋ฐ ์‹ค๋ฌด๋ฅผ ํ•  ๋•Œ๋Š” ์ด๋ ‡๋“ฏ ํ•˜๋‚˜์˜ ๋„๋ฉ”์ธ์ด ์•„๋‹Œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋„๋ฉ”์ธ์—์„œ ์‘๋‹ต์„ ๋ฐ›์•„์™€์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ข…์ข… ์žˆ๋‹ค. ์ด๋Ÿด ๋•Œ๋Š” ์œ ์—ฐํ•˜๊ฒŒ proxy๋ฅผ ์„ค์ •ํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค.

 

๊ทธ๋Ÿฌ๋ฏ€๋กœ webpack dev server์˜ ์ „์—ญ์ ์ธ proxy ์„ค์ • ๋Œ€์‹ , http-proxy-middleware์˜ proxy ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ Bookservice์™€ Todoservice 2๊ฐœ์˜ ๋„๋ฉ”์ธ์—์„œ ๋ชจ๋‘ ์‘๋‹ต์„ ๋ฐ›์•„์™€์•ผ ํ–ˆ๋‹ค. 

 

๋”ฐ๋ผ์„œ BookService.js์—๋Š” api์— ๊ด€๋ จ๋œ fetch ํ•จ์ˆ˜๋ฅผ, TodoService.js์—๋Š” api2์— ๊ด€๋ จ๋œ fetch ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๊ณ , ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•˜๋‚˜ ์ด์ƒ ๋งŒ๋“ค์–ด 2๊ฐœ์˜ ๋„๋ฉ”์ธ์—์„œ ๋ชจ๋‘ ์‘๋‹ต์„ ๋ฐ›์•„์˜ค๋Š”์ง€ ํ…Œ์ŠคํŠธ ํ•ด๋ณด๊ณ ์ž ํ–ˆ๋‹ค. webpack dev server proxy๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ๊ธฐ์กด์˜ fetch (ํ˜น์€ axios๋„ ๊ฐ€๋Šฅ)๋ฅผ ํ†ตํ•ด ์š”์ฒญํ•˜๋˜ ๋ถ€๋ถ„์—์„œ ๋„๋ฉ”์ธ ๋ถ€๋ถ„์„ ์ œ๊ฑฐํ•ด์•ผ ํ•˜๊ธฐ์— ์•„๋ž˜์™€ ๊ฐ™์ด ์ ์–ด์ฃผ์—ˆ๋‹ค. 

// my-app > src > services > BookService.js

export const getAllBooks = async () => {
    const response = await fetch("/api/books");
    return await response.json();
};

export const createBook = async (data) => {
    const response = await fetch("/api/book", {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({book: data})
    })
    return await response.json();
}

 

๊ฒฐ๋ก ์ ์œผ๋กœ ๋งํ•˜์ž๋ฉด, ์•„๋ž˜ TodoService.js์—์„œ ์ž˜๋ชป๋œ API๋กœ ์š”์ฒญํ•˜๊ณ  ์žˆ์—ˆ๊ธฐ์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒƒ์ด์—ˆ๋‹ค.

// my-app > src > services > TodoService.js

export const getAllTodos = async () => {
    const response = await fetch("/api/todos");
    return await response.json();
};

export const createTodo = async (data) => {
    const response = await fetch("/api/todo", {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({todo: data})
    })
    return await response.json();
}

 

 

๐Ÿ’ก ์—๋Ÿฌ ์›์ธ ํŒŒ์•…

1. ๋ธŒ๋ผ์šฐ์ € ๊ฐœ๋ฐœ์ž ๋„๊ตฌ > Network ํƒญ์—์„œ ์‚ดํŽด๋ณด๊ธฐ

๋ชจ๋“  my-app, api, api2 ๋ชจ๋“  ์„œ๋ฒ„๋ฅผ ๋‹ค ์ผœ๋‘์—ˆ๋‹ค๋Š” ์ „์ œ ํ•˜์—, ๋ธŒ๋ผ์šฐ์ € ์ƒ์—์„œ ์‹คํ–‰ ํ›„ ๊ฐœ๋ฐœ์ž๋„๊ตฌ๋ฅผ ์ผœ๊ณ  'Network' ํƒญ์„ ์‚ดํŽด๋ณด๋ฉด ์–ด๋Š์ •๋„ ๋‹ต์ด ๋‚˜์˜ฌ ๊ฒƒ์ด๋‹ค. ์œ„์˜ ์‚ฌ์ง„์—์„œ๋„ ๋ณด์ด๋“ฏ, ํ˜„์žฌ TodoService.js์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. todo ๋ฐ์ดํ„ฐ๋ฅผ ์ •์ƒ์ ์œผ๋กœ ์‘๋‹ต๋ฐ›์ง€ ๋ชปํ•˜๊ณ  ์žˆ๋‹ค. ์ด๋ฅผ ํด๋ฆญํ•ด๋ณด์ž.

 

2. Source ํƒญ์„ ์ฐธ๊ณ ํ•ด ๋””๋ฒ„๊น… ํ•ด๋ณด๊ธฐ

Source ํƒญ์„ ๋ˆŒ๋Ÿฌ๋ณด๋ฉด ์ •ํ™•ํžˆ ์–ด๋–ค ๋ถ€๋ถ„์œผ๋กœ ์ธํ•ด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ์•Œ๋ ค์ค€๋‹ค. ์ด๋ฅผ ์ฐธ๊ณ ํ•˜๋ฉด ๋””๋ฒ„๊น…์— ํฐ ๋„์›€์ด ๋œ๋‹ค. ์–ด์ด์—†๊ฒŒ๋„ TodoService๋Š” api๊ฐ€ ์•„๋‹ˆ๋ผ, 'api2'๋กœ ๋ฐ›์•„์™€์•ผ ํ•˜๋Š”๋ฐ api๋กœ ์จ๋‘์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด์—ˆ๋‹ค. ์ฆ‰, ์„œ๋ฒ„๊ฐ€ ์ œ๊ณตํ•˜๋Š” API ์—”๋“œํฌ์ธํŠธ(api2)๊ฐ€ ์•„๋‹Œ, ์ž˜๋ชป๋œ API(api)๋กœ ์š”์ฒญํ•˜๊ณ  ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒƒ์ด๋‹ค.

 

์•„๋ž˜์™€ ๊ฐ™์ด TodoService.js์—์„œ api๋ฅผ api2๋กœ๋งŒ ์ˆ˜์ •ํ•˜๋ฉด ๋์ด๋‹ค.

// my-app > src > services > TodoService.js

export const getAllTodos = async () => {
    const response = await fetch("/api2/todos");
    return await response.json();
};

export const createTodo = async (data) => {
    const response = await fetch("/api2/todo", {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({todo: data})
    })
    return await response.json();
}

 

๊ทธ๋Ÿผ ์•„๋ž˜์™€ ๊ฐ™์ด BookService์™€ books์™€ TodoService์˜ todos๋ฅผ ์ž˜ ๋ฐ›์•„์˜ค๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค!

 

 

๐Ÿ˜… Today I learned

์ง€๊ธˆ ๋Œ์•„๋ณด๋ฉด ๊ต‰์žฅํžˆ ์–ด์ด์—†๋Š” ๊ณณ์—์„œ ์‹ค์ˆ˜๋ฅผ ํ–ˆ๋‹ค. ๋ณ„์ƒ๊ฐ์—†์ด ๋ณต์‚ฌ ๋ถ™์—ฌ๋„ฃ๊ธฐ๋ฅผ ํ•œ ํƒ“์ด๋‹ค.

๋ญ ์‹ค์ˆ˜๋Š” ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ด๋ ‡๊ฒŒ ๋น ๋ฅด๊ฒŒ ๋””๋ฒ„๊น…์„ ํ•˜๋ฉฐ ๋ฌธ์ œ๋ฅผ ํŒŒ์•…ํ•˜๊ณ  ํ•ด๊ฒฐํ•˜๋ฉด ๋˜๋Š”๊ฑฐ๋‹ˆ๊นŒ!

 

๊ทธ๋ฆฌ๊ณ  ์ด๋ ‡๊ฒŒ ๊ธฐ๋กํ•ด์„œ ๋‹ค์Œ์—๋Š” ๊ฐ™์€ ์‹ค์ˆ˜๋ฅผ ํ•˜์ง€ ์•Š๋„๋ก!

 

 

๋Œ“๊ธ€