HTTP 헤더
HTTP 요청 메시지와 응답 메시지에 포함된 헤더를 통해 여러 형태의 메타데이터가 전달됨
HTTP는 표준 헤더 집합을 정의하고 그 중 일부는 요청된 리소스 관련 정보를 제공함
그리고 몇몇 헤더는
메시지에 전달되는 표현 관련 정보
를 나타내며, 중간 캐시를 조절하는 지시자 역할
을 하기도 함규칙
Content-Type
을 사용해야 한다
이 헤더는 요청이나 응답 메시지 바디에 있는 데이터 타입을 나타냄.
이 헤더의 값은 미디어 타입으로 알려진 특별하게 정의된 문자열임
클라이언트와 서버는 이 헤더 값을 참조하여 메시지 바디에 있는 바이트열 처리 방법을 결정함
Content-Length
를 사용해야 한다
- Content-Length 헤더는 바이트 단위로 바디의 크기를 나타냄
- 응답에서 이 헤더는 두가지 이유에서 중요
- 클라이언트는 이 값을 이용하여 바이트의 크기를 올바로 읽었는지 알 수 있음
- HEAD 요청을 사용하여 데이터를 다운로드하지 않고도 바디가 얼마나 큰지 알 수 있음
Last-Modified
는 응답에 사용해야 한다
- 이 헤더는 응답 메시지에만 사용한다. 이 응답 헤더의 값은 타임스탬프로, 리소스의 표현 상태 값이 바뀐 마지막 시간을 나타냄
- 클라이언트와 캐시 중간자는 이 헤더 값을 이용하여 클라이언트에 저장되어 있는 리소스 상태 표현의 갱신 여부를 결정함
ETag
는 응답에 사용해야 한다
ETag 값은 응답 엔티티(HTTP 메시지의 페이로드. 즉, 헤더와 바디)에 포함된 표현 상태의 특정 버전을 나타내는 일련의 문자열임
이 헤더는 항상 GET 메서드 요청에 대한 응답으로 보내져야 함
클라이언트는 조건부 If-None-Match 요청 헤더의 값에 따라 ETag 헤더 값을 나중에 사용할 GET 요청을 위해 저장할 수도 있음 (엔티티 태그 값이 바뀌지 않았다는 것을 알면, 표현을 다시 보내지 않음으로써 시간과 대역폭을 절약할 수 있음)
스토어는 조건부 PUT 요청을 지원해야 한다
- 스토어 리소스는 PUT 메서드를 사용하여 리소스를 새로 추가하거나 갱신할 수 있는데, 두 가지 용도로 사용이 되기에 REST API는 클라이언트가 사용한 PUT 메서드가 무엇을 위한 요청이었는지 파악하기 쉽지 않음
- If-Unmodified-Since와 If-Match 요청 헤더를 통해 클라이언트의 의도를 알 수 있음
- If-Unmodified-Since 요청 헤더는 API 에게 리소스의 상태 표현이 헤더 값에 표현된 타임스탬프 시간 이후로 바뀌지 않았을 경우에만 동작하도록 요구
- If-Match 헤더 값은 엔티티 태그인데, 클라이언트가 받은 이전 응답의 ETag 헤더 값임. 이 헤더는 요청을 조건부로 만드는데
헤더에 제공된 엔티티 태그 값
과 REST API에 의해 저장되거나 계산된표현 상태의 현재 태그 값
의 정확한 비교에 기초함
Location
은 새로 생성된 리소스의 URI를 나타내는 데 사용해야 한다
- Location 응답 헤더의 값은 클라이언트의 관심 범위에 있는 리소스를 식별하는 URI임
- 컬렉션이나 스토어에 성공적으로 리소스를 생성했다는 응답이며, REST API는 Location 헤더를 포함해서 새로 생성된 리소스의 URI를 나타내야 함
- 202(”Accepted”) 응답 안에 있느 이 헤더 값은 비동기 컨트롤러 리소스의 연산 상태를 클라이언트에 정확히 알려주는 데 사용할 수 있음
Cache-Control
, Expires, Date 응답 헤더는 캐시 사용을 권장하는 데 사용해야 한다
Cache-Control, Expires, Pragma 응답 헤더는 캐시 사용을 중지하는 데 사용해야 한다
Cache-Control 헤더 값 : no-cache 혹은 no-store
HTTP 1.0 캐시와의 상호 운영을 고려한다면
Pragma : no-cache
Expires: 0
캐시 기능은 사용해야 한다
REST API는 꼭 필요한 경우가 아니면 캐시 사용하지 않음. no-cache 지시자를 추가하는 대신 값이 작은 max-age를 사용하면, 클라이언트는 갱신에 관계없이 짧은 시간 내 캐시에 저장된 복사본을 가져올 수 있음
만기 캐싱 헤더는 200(”OK”) 응답에 사용해야 한다
만기 캐싱 헤더는 성공적인 GET 메서드와 HEAD 메서드의 요청에 대한 응답으로 설정해야 한다.
다른 메서드에 만기 헤더를 지정해서는 안 된다.
만기 캐싱 헤더는 ‘3xx’와 ‘4xx’ 응답에 선택적으로 사용될 수 있다
이 방법을 ‘네거티브 캐싱’이라 하는데, 리다이렉트 횟수와 REST API 오류에 따른 부하를 감소시킴
커스텀 HTTP 헤더는 HTTP 메서드의 행동을 바꾸는 데 사용해서는 안 된다
- 커스텀 헤더는 정보 전달이 목적일 때만 선택적으로 사용할 수 있다
- 클라이언트와 서버에서 커스텀 헤더에 대해 처리하지 못하는 경우라도, 클라이언트와 서버 양쪽에서 문제가 없도록 구현해야 한다.
- 커스텀 HTTP 헤더로 전송하려는 정보가 응답이나 요청을 적절하게 처리하는 데 중요한 정보라면, 그 정보는 요청이나 응답의 바디에 포함하거나 요청 URI에 포함시켜야 한다.
미디어 타입
요청이나 응답의 메시지 바디 안에 있는 데이터 형태를 식별하기 위해 Content-Type 헤더 값을 미디어 타입이라고 함
미디어 타입 문법
type “/” subtype (”;” parameter)
- 계층적인 형태로, 미디어 타입의 서브 타입 값은 type의 부차적인 값이 됨
type/subtype 다음에 ‘attribute=value’와 같은 형태로 파라미터를 쓸 수 있는데, 이런 경우에는 세미콜론(;)으로 분리함
- 파라미터 이름은 대소문자를 구분하지 않으나
- 파라미터 값은 보통 대소문자를 구분하고 큰따옴표 안에 씀
- 파라미터를 하나 이상 사용할 경우, 순서는 중요하지 않음
type의 종류
- application
- audio
- image
- message
- model
- multipart
- text
- video
- 예시
Content-type: text/html; charset=ISO-8859-4
Content-type: text/plain; charset=”us-ascii”
등록된 미디어 타입
IANA(Internet Assigned Numbers Authority) : 글로벌 IP 주소 할당, 미디어 타입 등록 등 인터넷에서 관리가 필요한 업무를 담당하는 기관
- text/plain
- text/html
- image/jpeg
- application/xml
벤더 고유 미디어 타입
- 벤더 고유 미디어 타입은 서브 타입의 접두어로
vnd
를 사용하며, 특정 업체에서 소유 및 관리하고 있음을 의미함
- 예시
- application/vnd.ms-excel
- application/vnd.lotus-notes
미디어 타입 설계
- 클라이언트 개발자들은 REST-API의 자기-서술적 특성을 활용하는 것이 좋음 ↔ 클라이언트 프로그램에는 특정 API의 세부 사항에 대한 하드코딩된 부분이 가능한 한 적은 것이 좋음
규칙
애플리케이션 고유 미디어 타입을 사용해야 한다 (조금 과해보이긴 함)
리소스의 표현이 여러 가지 가능할 경우 미디어 타입 협상(Media type negotiation)을 지원해야 한다
- 클라이언트에서 원하는 미디어 타입을 Accept 헤더에 추가하여 특정 포맷과 스키마를 협상할 수 있게 해야 한다.
Accept: application/json
이렇게 로우 미디어 타입을 이용하여 REST API의 응답을 표시하게 할 수 있음
query 변수를 사용한 미디어 타입 선택을 지원할 수 있다
- 단순 링크와 쉬운 디버깅이 가능하도록 REST API는 Accept HTTP 요청 헤더 값과 동일한 쿼리 파라미터 accept를 통해 미디어 타입을 선택하도록 할 수 있다.
- 예) GET /bookmarks/mikemassedotcom?accept=application/xml
- 위 방법은 URI 패스에 ‘.xml’ 등 가상 파일 확장자를 추가하는 방법보다 명확하고 일반적인 것으로 널리 사용됨
쿼리 파라미터를 통한 미디어 타입 선택과 협상은 HTTP의 의도된 위치(Accpet 헤더)가 아닌, URI에 메타데이터를 실어 보내는 터널링의 한 형태다. 따라서 주의해서 사용해야 한다