230615 express res.format()으로 Accept HTTP Header에 따라 다른 콘텐츠 응답하기
230615 express res.format()으로 Accept HTTP Header에 따라 다른 콘텐츠 응답하기
res.format()을 사용하면 사용자가 보낸 http 요청에 대해 서버는 사용자가 원하는 타입으로 데이터를 줄 수 있다.
Accept HTTP Header
Http header 필드 중 하나인 Accept는 MIME 타입으로 표현되고, 서버에게 클라이언트가 이해 가능한 타입이 무엇인지 알려주는 역할을 한다. 서버에서는 이 값을 바탕으로 클라이언트에게 응답을 어떤 형식으로 할지 결정할 수 있다.
Accept 필드가 없는 경우
이 경우에는 클라이언트가 모든 미디어 타입을 수락할 수 있다고 가정한다.
Accept : */*
Accept 필드가 있지만 수락할 수 있는 타입의 응답이 없는 경우
이 경우에는 406(Not Acceptable) 응답을 반환해야 한다.
res.status(406).send('Not Acceptable')
q 품질 계수
응답 가능한 타입을 여러 개로 설정할 때, q 값을 통해 우선순위를 정할 수 있다.
q값은 0~1사이의 값으로 상대적인 품질 계수를 의미한다.
q값이 높은 타입이 우선순위가 높으며,
q값이 같은 두 개 이상의 타입이 대해서는 더 구체적인 타입이 우선순위를 갖는다.
res.format(object)
Accept 헤더 필드 값을 바탕으로 콘텐츠를 다르게 보내기 위해 사용한다.
객체값을 매개변수로 받으며, 객체의 키 값으로는 MIME 타입, 값으로는 콜백 함수를 받는다.
Accept가 없는 경우
첫 번째 콜백 함수가 실행된다. 따라서 가장 일반적인 타입이 맨 앞에 오는 것이 좋다.
일치하는 MIME 타입이 없는 경우
마지막 default를 실행하여 406에러를 반환한다.
app.post('/api', upload.none(), (req, res) => {
const { accept } = req.headers;
const { name } = req.body;
console.log('name: ', name, 'accept: ', accept);
res.format({
'text/plain': () => res.send(name),
'text/html': () => res.send(`<h2>${name}</h2>`),
'application/json': () => res.send({ name: name }),
default: () => res.status(406).send('Not Acceptable'),
});
});
예제
text/plain, text/html, application/json에 대해 각각 text, html, json으로 반환하는 서버.
image/jpeg타입은 지원하지 않으므로 406 에러를 반환한다.