next.config.js에서 rewrites 옵션을 사용하면 next 서버가 일종의 proxy 역할을 하도록 구현할 수 있다.
요청 url을 숨기고 싶을 때 따로 API를 구현하지 않아도 되고 머리 아픈 CORS 에러도 간단하게 해결할 수 있어서 종종 사용하는데, url에 query parameter
를 적용하다가 삽질했던 기록을 남겨본다.
path parameter 제대로 이해하기
/aladin-api?QueryType=Bestseller
와 같은 요청을 처리하고 싶을 때, 해당 요청의 path는 /aladin-api
이다.
module.exports = {
async rewrites() {
return [
{
source: '/aladin-api',
destination: `${process.env.ALADIN_OPEN_API}/api`,
},
];
},
};
source 필드에 정규표현식으로 query parameter key를 매치해보려고 시도하면 안된다.. 404 만남!😅
has 사용하기
대신 특정 query parameter가 포함되어 있는지 확인하기 위해 사용할 수 있는 필드가 있는데, 바로 has
이다.
module.exports = {
async rewrites() {
return [
{
source: '/aladin-api',
/** /aladin-api?QueryType=Bestseller 요청에 매치된다. */
has: [
{
type: 'query',
key: 'QueryType',
value: 'Bestseller',
},
],
destination: `${process.env.ALADIN_OPEN_API}/api?QueryType=Bestseller`,
},
];
},
};
query parameter의 value 값을 그대로 destination에 넣고 싶다면, named capture group을 사용해야 한다. (query key를 변수처럼 사용할 수는 없다.)
module.exports = {
async rewrites() {
return [
{
source: '/aladin-api',
/** /aladin-api?QueryType=* 요청에 매치된다. */
has: [
{
type: 'query',
key: 'QueryType',
value: '(?<QueryType>.*)',
},
],
destination: `${process.env.ALADIN_OPEN_API}/api?QueryType=:QueryType`,
},
];
},
};
has
는 query parameter 뿐만 아니라 header나 cookie에 특정 값이 포함되어 있는지 확인할 때 사용할 수도 있다.
주의할 점
has 필드로 전달되는 모든 query key가 존재해야지만 매칭된다는 점에 주의해야 한다. (아주.. 섬세한 친구이다..🫠)
module.exports = {
async rewrites() {
return [
{
source: '/aladin-api',
/**
* /aladin-api?QueryType=*&Cover=* 요청에 매치된다.
* /aladin-api?Cover=*&QueryType=* (O)
* /aladin-api?QueryType=* (X)
* /aladin-api?Cover=* (X)
*/
has: [
{
type: 'query',
key: 'QueryType',
value: '(?<QueryType>.*)',
},
{
type: 'query',
key: 'Cover',
value: '(?<Cover>.*)',
},
],
destination: `${process.env.ALADIN_OPEN_API}/api?QueryType=:QueryType&Cover=:Cover`,
},
];
},
};
마무리
간단한 API에서 활용하기에는 문제가 없어 보이지만, 더 범용적으로 사용되는 API라면 rewrites 옵션만으로는 분기 처리가 쉽지 않아 별도의 API를 구축하는게 더 효율적일 것 같다.