처음 시작하자 마자 겪은 에러이다.
프론트에서 백으로 api요청을 하자 다음과 같은 에러가 콘솔에 떴다.
대충 읽어보니 CORS 정책으로 막혔다고 한다, 이후 CORS에 대해서 구글링해봤다.
cors란 브라우저에서 cross-origin 요청을 안전하게 할 수 있도록 하는 메커니즘이다, 그럼 cross-origin이란?
다음 중 한 가지라도 다른 경우을 cross-origin이라 한다
구체적으로는 브라우저에서는 보안적인 이유로 cross-origin HTTP 요청들을 제한한다, 그래서 cross-origin 요청을 하려면 서버의 동의가 필요 만약 서버가 동의한다면 브라우저에서는 요청을 허락하고, 동의하지 않는다면 브라우저에서 거절한다.
이러한 허락을 구하고 거절하는 메커니즘을 HTTP-header를 이용해서 가능한데, 이를 CORS(Cross-Origin Resource Sharing)라고 부릅니다.
나의 경우 프론트 서버인 http://localhost:3000/에서 백 서버인 http://localhost:8000/에 요청을 하여 발생하였다.
express에서 해결방법은 간단하다
npm install cors 이후
const cors = require('cors');
const corsOptions = {
origin: '*', // 출처 허용 옵션
credential: true, // 사용자 인증이 필요한 리소스(쿠키 ..등) 접근
};
app.use(cors(corsOptions));
다음과 같이 설정 해준다
서로 다른 url이 소통하기 위해서는 보안을 위해 허락하는 과정이 필요하다고 기억하자
페이지를 여러개 만들면서 react-router-dom v6를 사용했는데 문득 페이지 이동시 2가지 방법을 혼합하고 사용하고 있음을 깨달았따.
react-router-dom v6를 처음 사용했을때는 클론 코딩이라 그저 따라치기 바빠서 넘어갔는데, 실제로 구현하니 같은 기능을 하는 두가지 문법이 있었다.
axios를 사용한 코드를 테스트하기 위해 jest의 mock을 사용해야겠다고 생각했지만 구체적으로 어떤 jest 문법을 사용할지 몰랐다.
jest문법을 읽어보면서 mockImplementationOnce
가 적절하다고 느꼈다.
given / when / then의 테스트 패턴도 기억하자
describe('getPost test', () => {
const postId = 1;
test('when success, return postInfo', async () => {
// given
const res = {
data: [
{
postId,
tite: 'title-test1',
singer: 'singer-test1',
content: 'content-test1',
userIp: '0.0.0.0',
registerDate: '2022-12-11T05:00:24.000Z',
},
],
};
axios.get.mockImplementationOnce(() => Promise.resolve(res));
// when
const result = getPost(postId);
// then
await expect(result).resolves.toEqual(res);
expect(axios.get).toHaveBeenCalledWith(`/post/${postId}`);
});
test('when fail, return null', async () => {
// given
const errorMsg = 'Network Error';
axios.get.mockImplementationOnce(() => Promise.reject(new Error(errorMsg)));
// when
const result = getPost(postId);
// then
await expect(result).resolves.toEqual(null);
expect(axios.get).toHaveBeenCalledWith(`/post/${postId}`);
});
});
프로젝트에서는 따로 에러핸들링을 하지않고 null을 리턴하여 끝냈지만, 팀 프로젝트에서는 에러 핸들링도하여서 에러가 난 상황을 mock으로 구현, 에러 핸들링 테스트도 할 수 있도록 해야겠다
리액트 설계패턴을 많이 찾아봤는데 mvc, mvvm, mvp 등을 찾아봤지만 프론트에서는 사용 사례나, 예시 코드를 찾기 힘들었다. 하지만 위 디자인 패턴의 공통점은 모두 view <-> logic을 구분하는 것이며 프론트엔드의 디자인 패턴에 설명하는 글들도 모두 공통적으로 view와 logic의 분리를 중요시 여긴다고 언급하고 있었다
그래서 view <-> logic을 분리하는 리액트의 2가지 패턴을 찾았다.
이중 hooks을 사용한 두번째 패턴이 ui와 더불어 logic도 hooks으로 재사용이 가능해서 더 좋다는 설명이 두번째 Component - custom hooks패턴을 사용했다.