REST-Accept 헤더와 확장을 통한 컨텐츠 협상 간의 절충


40

RESTful API 설계를 진행하고 있습니다. 주어진 리소스에 대해 JSON과 XML을 반환하려고합니다. 나는 우리가 다음과 같이 할 것이라고 생각했습니다.

GET /api/something?param1=value1
Accept:  application/xml (or application/json)

그러나 누군가 다음과 같이 확장 기능을 사용하여 던졌습니다.

GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

이러한 접근 방식의 장단점은 무엇입니까? 확장명이 지정되지 않은 경우 accept 헤더를 사용하는 것이 가장 좋지만, 지정된 경우 확장을 존중하는 것이 가장 좋습니까? 그 접근법에 단점이 있습니까?


어떤 웹 서버를 사용하고 있습니까? URL을 어떻게 파싱합니까?
Dipan Mehta

1
나는 기술적 (서버) 측면에 대해 전혀 모른다. 즉, http 표준을 사용하기 때문에 접근 방식을 선호합니다. accept 가 지정되지 않았거나 예기치 않은 값이있는 경우 확장에 의존 할 수 있지만 항상 표준 방법을 먼저 사용합니다.
Treb

@ Dipan MVC4 Web API (아직 베타 버전)로 이것을 해킹하고 있습니다. ASP.NET의 라우팅 추상화를 사용합니다.
Brandon Linton

1
@Treb 그래, accept 헤더 값을 사용하는 팬이 훨씬 더 많다. 두 가지 모두를 지원하는 데 어떤 단점이 있는지 궁금합니다.
Brandon Linton

답변:


38

그러나 "철학적으로-첫 번째 방법은 유일한 방법"입니다. "적절한 공식 RESTful 방법은 Accept : 헤더를 사용하는 것입니다." 사실로 널리 인식 되어 있지만 절대적으로 잘못되었습니다 .

Roy Fielding (REST를 정의한 사람)의 짧은 발췌문은 다음과 같습니다.

"섹션 6.2.1은 콘텐츠 협상이 항상 사용되어야한다고 말하지 않습니다." 인용문

이 특정 대화는 'Accept-Language :'헤더와 관련이 있지만 나중에 응답에서 명확하게 알 수 있듯이 'Accept :'헤더에도 동일하게 적용됩니다.

"왜 사람들이 첫 페이지에서 두 번째와 세 번째 링크를 볼 수 없는지 모르겠습니다.

http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

"두 PDF 버전을 가리 킵니다."

그가 의미하는 바는 동일한 소스 데이터의 다른 표현에 다른 엔드 포인트를 사용하는 데 아무런 문제가 없다는 것입니다. (이 경우 하나의 .html 끝점과 두 개의 다른 .pdf 끝점입니다.)

비슷한 토론에서 이번에는 쿼리 매개 변수를 사용하는 것과 다른 미디어 유형에 대한 파일 확장자를 사용하는 것의 미덕에 관한 것입니다 ...

"그래서 항상 확장 기능을 선호합니다. 어느 쪽도 REST와 관련이 없습니다." 인용문

다시 말하지만, Accept와 파일 이름 확장자는 약간 다르지만 Fielding의 입장은 여전히 ​​명확합니다.

답변-그것은별로 중요하지 않습니다. 둘 사이의 절충은 그다지 중요하지 않으며 둘 다 허용되는 스타일입니다.


3
균형 잡힌 답변. 때로는 특정 콘텐츠가 의도 한 URI에서 '분명히'추가한다고 생각합니다. 예를 들어 URI의 .html 확장자 또는 .pdf 확장자입니다. 이 경우 콘텐츠 협상을 지원할 필요가 없으며 URI에 콘텐츠를 암시 적으로 적용하면 사람이 URI를 더 쉽게 공유하고이를 사용하여 즉시 사용할 수있는 방식으로 사물에 연결하는 것이 더 쉬워집니다. URI에서 확장을 피하거나 여러 컨텐츠 유형 json / XML을 동일하게 지원하는 웹 API를 노출하려는 경우와 같이 승인 헤더가 더 적합 할 수 있습니다.
Tim Lovell-Smith

새 링크를 포함하도록 답변이 업데이트되었습니다. 야후 그룹의 구조가 바뀌 었다고 생각합니다.
Phil Sturgeon

동의하지 않습니다. 서버가 리턴하는 자원 설명 언어는 서비스 엔드 포인트가 수행하는 비즈니스 로직과 관련이 없어야합니다. 다른 자원 설명 언어를 수용하기 위해 동일한 서비스 엔드 포인트에 대해 여러 개의 URI를 갖는 것은 REST URI를 구성하는 방법에 대한 오해처럼 보입니다.
Dejay Clayton

10

적절한 공식 RESTful 접근 방식은 Accept:헤더 를 사용하는 것 입니다.

그러나 REST 요구 사항 중 하나 인 캐시 가능성을 위반하지 않도록주의해야합니다. Vary: Accept이를 이해하는 헤더와 캐시 가 있어야 합니다. 이상적인 세상에서는 그럴 것이지만 실제로는 밀레가 다를 수 있습니다. 따라서 두 번째 해결책은 깨끗하지 않지만 더 실용적입니다.

또한 일부 오래된 브라우저는 확장을 사용하여 헤더를 무시하는 데 사용되었습니다.


1
사실 부정확합니다. 허용 된 답변을 참조하십시오.
Phil Sturgeon

9

기술적으로는 중요하지 않습니다. 웹 서버는 원하는대로 적절하게 프로세스를 전달할 수 있습니다. (나는 이것을 가정하고 있지만 showtopper처럼 보이지 않습니다).

그러나 철학적으로 첫 번째 방법은 유일한 방법입니다. REST에서 URL은 실제로는 리소스 인 URI 만 가리 킵니다. 잠시이 생각 자원 과 동일 객체 객체 지향 프로그래밍을. 당신은 이야기 만 4 방법 (일명 GET / POST / PUT / DELETE - 또는 아무것도 전송이 허용하는 경우)를 통해이 자원에 있지만 그 방법이되지 않습니다 설명 개체를. 같은 방식으로 반환 값이 URI가 아닌 측면. 객체는 여전히 뭔가 이며 something.xml 또는 something.json이 아닙니다.

Accept 헤더를 사용하고 싶지 않지만 여전히 철학적으로 진정으로 휴식을 취하고 싶다면 다음과 같이 신경 쓰지 마십시오.

GET /api/something?parm1=value1&return_type=xml

반대로

GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

그러나 내가 말했듯이,이 차이는 단지 철학적입니다.


+1 Dipan, 당신은 한 가지를 제외하고 옳습니다 : / api / something? return_type = xml is still restus . RESTful하지 않은 이유는 URL이 불투명하기 때문입니다. IOW는 프로토콜 관점에서 / api / something / xml과 / api / something? xml간에 차이가 없습니다. w3.org/DesignIssues/Axioms.html을 참조하십시오 .
Mark E. Haase 2018 년

0

@ vartec : 나는 당신이 잘못 생각

적절한 공식 RESTful 원칙에 따르면 노출되거나 참조되는 URI이므로 HTTP 헤더에 아무것도 숨겨서는 안되며 요청 / 응답에 대한 세부 정보는 URI의 일부로 제공되어야합니다

따라서 요청 및 응답에 대한 세부 정보를 위해 헤더를 사용하지 말고 강력히 권장합니다.

 GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

참고 문헌을 빨리 찾을 수는 없지만 참조와 함께 다시 게시 할 것입니다 (실제로 O'reilly 출판물 "RESTful 웹 서비스"( http://shop.oreilly.com/product/9780596529260.do )을 참조 할 수 있음 ) 같은 것을 확인


17
-1 완전히 잘못되었습니다. 우선 URL HTTP 헤더로 전송됩니다. 또한 각 고유 URL은 고유 한 리소스를 나타내야합니다. 동일한 콘텐츠의 XML 및 JSON 인코딩은 분명히 다른 리소스가 아닙니다. 그것들은 동일한 자원의 두 가지 다른 표현입니다.
Mark E. Haase 2016 년

HTTP 헤더는 보안 자격 증명, 상관 관계 식별자, 세션 ID, 트랜잭션 컨텍스트, 데이터 형식과 같은 "메시징 메타 데이터"를 저장하는 합법적이고 권장되는 장소입니다. 이런 종류의 정보는 URL이나 메시지 페이로드를 복잡하게하지 않아야합니다.
Paulo Merson
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.