개요
저번 "(2) - Express 디렉토리 구조 설정, 채팅 room 생성 API 만들기" 편에서는 채팅방을 생성하는 서버측 코드를 작성했다.
[Project] Youtube Party 만들기 (2) - Express 디렉토리 구조 설정, 채팅 room 생성 API 만들기
채팅인데 방 생성 API를 만드는 이유 나는 기존에 튜토리얼에서 흔히 하듯이 유저가 직접 방 이름을 입력해 socket 채팅방에 참여하는 방식이 아니라, 서버에 의해 방 이름을 받아 접속하도록 하고
bluepebble25.tistory.com
이번 시간에는 그렇게 생성한 방 생성, 조회 API를 가지고 클라이언트측에서 채팅방 페이지로 이동하는 기능을 만들 것이다. 그 과정에서 만약 유효하지 않은 roomId 페이지로 이동했다면 getServerSideProps 함수를 이용해 404 에러 페이지로 리다이렉트 하도록 할 것이다.
코드 전문은 github에서 볼 수 있다.
에러 페이지 만들기
내가 만들 사이트의 채팅방 url은 "localhost:3000/party/:roomId" 형식인데,
존재하지 않는 roomId로 이동했을 때 등 특정 상황을 안내해주는 화면과,
아예 localhost:3000/wrongggg/dsdksdkwek 처럼 아예 말도 안되는 링크로 이동할 때를 대비한 포괄적인 404 페이지를 나누어서 보여주고 싶었다.
그래서 client/pages에 404.tsx와 oops.tsx 페이지 두 가지를 만들었다.
포괄적인 에러 페이지 (404.tsx)
function NotFound() {
let errorMessage = '페이지를 찾을 수 없습니다.';
return <h2>404 Error: {errorMessage}</h2>;
}
export default NotFound;
특정 상황을 안내하는 페이지 - ex) 유효하지 않은 roomId 등 (oops.tsx)
import { useRouter } from 'next/router';
function Oops() {
const router = useRouter();
const { query } = router;
let errorMessage = '페이지를 찾을 수 없습니다.';
if (query.reason === 'room-not-found') {
errorMessage = '유효하지 않은 방 코드입니다.';
}
return <h2>404 Error: {errorMessage}</h2>;
}
export default Oops;
oops 페이지는 리다이렉트 시킬 때 '/oops?reason=room-not-found' 이런 식으로 쿼리에 이유를 적어서 특정 상황에 대한 안내문을 출력하도록 했다.
코드에 나온 room-not-found 상황 외에도 추가로 상세한 안내가 필요할 때 reason을 추가하면 된다.
방 유효성 여부에 따라 리다이렉트
구글미트처럼 채팅방 입장 버튼을 갖춘 메인 페이지를 만들어준다. 버튼을 클릭하면 채팅방 페이지로 이동하게 된다.
그런데 채팅방 페이지에 진입하기 전, getServerSideProps를 이용해서 roomId 유효성을 검사한 후 여부에 따라 리다이렉트를 시키기로 했다.
getServerSideProps에서 roomId 파라미터를 어떻게 읽을 수 있을까?
페이지를 요청할 때 어떤 쿼리가 함께 왔는지 서버사이드 렌더링 시간에 알려면 getServerSideProps 함수로 들어오는 파라미터인 GetServerSidePropsContext, 줄여서 ctx를 이용하면 된다. ctx.query로 서버사이드 렌더링 시점에서 파라미터를 가져올 수 있다.
pages/[roomId].tsx
서버사이드 함수에서 rooms API에 GET 메소드로 요청을 보내, 채팅방에 입장하기 전에 url의 roomId 파라미터가 유효한지 검사하고, 유효성 여부에 따라 리다이렉트를 하는 로직이다.
GET 요청을 하게 되면 서버는 rooms 목록에서 roomId 방이 존재하는지 알려주게 된다.
(존재한다면 방 데이터를 반환하고, 존재하지 않는다면 status 404 반환)
export default function Room() {
// 채팅방 페이지 코드
}
// 방 id 유효성 검사 후 유효성 여부에 따라 리다이렉트
export async function getServerSideProps(ctx: GetServerSidePropsContext) {
const { roomId } = ctx.query;
// API 요청해서 방 존재하는지 유효성 검사하고 찾지 못해 status 404면 리디렉션
try {
const res = await axios.get(`${SERVER_URL}/api/rooms/${roomId}`);
return {
props: {},
};
} catch (e: any) {
const { response } = e as unknown as AxiosError;
if (response?.status === 404) {
return {
redirect: {
destination: '/oops?reason=room-not-found',
permanent: false,
},
};
}
return {
props: {},
};
}
}
getServerSideProps 함수
이 함수는 위의 리다이렉트 로직처럼 반환할 값이 전혀 없어도 어떤 값을 반환해야하기 때문에, 반환할 값이 없을 때는 빈 객체를 반환하면 된다.
만약 반환하지 않으면 getServerSideProps 함수가 종료되지 않아 네트워크 탭을 보면 페이지 요청이 Pending으로 나온다.
보통은 getServerSideProps 함수를 서버 사이드에서 데이터를 prefetching 하는 용도로 사용하지만, 리다이렉트를 하기 위해 사용할 수도 있다. redirect 객체를 반환하면 된다.
next.config.js의 rewrites()에서 반환하는 객체와 비슷하게 생기지 않은가?
그와 비슷하게 redirect 객체 안에 destination과 기타 옵션을 넣어주면 된다. 참고로 permanent는 이 리디렉션이 영구적인지 여부를 알려주는 것이다. 내 경험상 true, false 여부는 별로 중요하지 않은 것 같고 주로 다른 프로그래머한테 정보를 주는 용인 것 같다.
'프로젝트 과정 기록' 카테고리의 다른 글
[Project] Youtube Party 만들기 (4) - socket 모듈 만들기 (Nextjs, Express로 채팅 기능 구현) (0) | 2023.10.23 |
---|---|
[Project] Youtube Party 만들기 (2) - Express 디렉토리 구조 설정, 채팅 room 생성 API 만들기 (0) | 2023.10.06 |
[Project] Youtube Party 만들기 (1) - 프로젝트 환경설정 | Nextjs + Typescript + Express (0) | 2023.09.23 |
[Project] Youtube Party 만들기 - 프로젝트 주제, 컨셉 (0) | 2023.09.22 |
[React] Chartjs로 막대그래프 그리기 (0) | 2023.08.04 |