리버스 프록시는 클라이언트와 서버 중 서버 측에 위치하여 클라이언트의 요청을 백엔드에 대신 전달해주는 역할을 수행합니다. 일반적으로 프론트엔드와 백엔드를 각각 별도로 구성한 경우에는 CORS 에러를 방지하거나 백엔드 서버에 대한 요청을 분산시키기 위해 Nginx를 활용하여 프록시를 설정하는 경우가 많습니다. 클라이언트가 직접 백엔드와 통신하지 않고 프록시가 대신 서버 대 서버 형태로 통신하여 필요한 데이터를 주고 받기 때문에 보안 측면에서도 비교적 안전합니다.
Next.js는 프론트엔드 라이브러리인 React를 기반으로한 풀스택 웹 프레임워크로서 자체적으로 프록시 기능을 지원하고 있습니다. 따라서 Nginx 웹 서버를 별도로 구성하여 설정을 적용할 필요없이 간단한 설정을 몇 줄 작성하는 것만으로도 리버스 프록시를 통해 백엔드 서버와 통신할 수 있습니다.
실습은 아래의 Next.js, Spring Boot 어플리케이션을 통해 진행됩니다. 저장소를 clone 하거나 fork 해주세요.
예시 프로젝트의 next.config.mjs
에는 다음과 같이 rewrites()
가 작성되어 있습니다. source
는 Next.js 어플리케이션 자신의 라우팅 경로를 가리키며, destination
은 내부 혹은 외부의 목적지 경로를 가리킵니다. :/path*
라고 입력되어 있는 부분은 동일한 라우팅 규칙이 적용된다는 의미입니다. 내부적으로 리버스 프록시를 활용하기 위해서 NEXT_PUBLIC_API_ORIGIN
에 목적지 백엔드 서버의 URL을 입력해주어야 합니다.
/** @type {import('next').NextConfig} */
const nextConfig = {
async rewrites() {
return [
{
source: '/:path*',
destination: `${process.env.NEXT_PUBLIC_API_ORIGIN || 'http://localhost:8080'}/:path*`
}
];
}
};
export default nextConfig;
클라이언트 사이드 컴포넌트인 src/app/components/UsersList.js
에서 CRUD 요청을 하기 위한 fetch()
의 인수로 외부의 백엔드 주소가 아닌 자기 자신의 라우팅 경로를 입력합니다. 실제로는 내부적으로 프록시 처리가 되어 원격지의 백엔드 서버에 요청이 전달됩니다.
'use client';
import { useState, useEffect } from 'react';
const apiPath = process.env.NEXT_PUBLIC_API_PATH || '/api/users';
async function fetchUsers() {
const res = await fetch(apiPath);
if (!res.ok) {
throw new Error('Failed to fetch users');
}
return res.json();
}
async function createUser(user) {
const res = await fetch(apiPath, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(user),
});
if (!res.ok) {
throw new Error('Failed to create user');
}
return res.json();
}
...(이하 생략)
클라우드타입의 프로젝트 페이지에서 ➕ 버튼을 누르고 Spring Boot를 선택한 후, 미리 fork 해놓은 springboot-crud-example 를 선택합니다. 기타 설정은 아래를 참고하여 입력한 후 배포하기 버튼을 클릭합니다.
배포가 완료되면 접속하기 버튼을 누르고 주소창에 /api/users
경로를 추가하여 접속한 후 초기 데이터가 조회되는지 확인합니다.
클라우드타입의 프로젝트 페이지에서 ➕ 버튼을 누르고 Next.js를 선택한 후, 미리 fork 해놓은 nextjs-proxy-example 를 선택합니다. 기타 설정은 아래를 참고하여 입력한 후 배포하기 버튼을 클릭합니다.
NEXT_PUBLIC_API_ORIGIN
: Spring Boot API URL(라우팅 경로 제외)NEXT_PUBLIC_API_PATH
: Spring Boot API 요청 라우팅 경로배포가 완료되면 접속하기 버튼을 눌러 페이지 및 데이터가 잘 로드되는지 확인합니다.