내일배움캠프

230615 express res.format()으로 Accept HTTP Header에 따라 다른 콘텐츠 응답하기

Neda 2023. 6. 15. 20:16

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 에러를 반환한다.