Search
📟

Proxy 설정 시 API 요청하기

Created
2023/06/11
Tags
API
Category
Troubleshoot
Parent item
Sub-item
2 more properties

오늘의 에러

React Proxy 설정 중, 오늘은 아래와 같이 두 에러를 만났다.
GET http://localhost:3001/api/todos 404 (Not Found)
JavaScript
복사
Uncaught (in promise) SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON
JavaScript
복사

처음 작성한 코드

레포지토리 안에는 Bookservice를 제공하는 api 폴더와 Todoservice를 제공하는 api2라는 두 폴더가 있다. 실제로 프로젝트 및 실무를 할 때는 이렇듯 하나의 도메인이 아닌 여러 개의 도메인에서 응답을 받아와야 하는 경우가 종종 있다. 이럴 때는 유연하게 proxy를 설정할 필요가 있다.
그러므로 webpack dev server의 전역적인 proxy 설정 대신, http-proxy-middleware의 proxy 기능을 사용하여 BookserviceTodoservice 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(); }
JavaScript
복사
결론적으로 말하자면, 아래 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(); }
JavaScript
복사

에러 원인 파악

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(); }
JavaScript
복사
그럼 아래와 같이 BookService와 books와 TodoService의 todos를 잘 받아오는 것을 볼 수 있다!

Today I learned

지금 돌아보면 굉장히 어이없는 곳에서 실수를 했다. 별생각없이 복사 붙여넣기를 한 탓이다. 뭐 실수는 할 수 있지만, 이렇게 빠르게 디버깅을 하며 문제를 파악하고 해결하면 되는거니까!
그리고 이렇게 기록해서 다음에는 같은 실수를 하지 않도록!