답변:
v4가 v3과 다른 리소스를 식별하기 때문에 URI 자체 (옵션 1)의 일부로 만드는 것이 가장 좋습니다. 두 번째 옵션과 같은 쿼리 매개 변수 는 리소스가 아닌 요청 과 관련된 추가 (쿼리) 정보를 전달하는 데 가장 잘 사용할 수 있습니다 .
URL을 버전 화하지 마십시오.
리소스가 application / vnd.yourcompany.user + xml의 변형을 반환한다고 가정하면 새 application / vnd.yourcompany.userV2 + xml 미디어 유형에 대한 지원을 만들고 v1과 콘텐츠 협상의 마법을 통해 v2 클라이언트는 평화롭게 공존 할 수 있습니다.
RESTful 인터페이스에서 계약에 가장 가까운 것은 클라이언트와 서버간에 교환되는 미디어 유형의 정의입니다.
클라이언트가 서버와 상호 작용하는 데 사용하는 URL은 이전에 검색된 표현에 임베드 된 서버에서 제공해야합니다. 클라이언트가 알아야하는 유일한 URL은 인터페이스의 루트 URL입니다. URL에 버전 번호를 추가하는 것은 클라이언트에서 URL을 구성하는 경우에만 가치가 있으며 RESTful 인터페이스로 수행 할 수는 없습니다.
기존 클라이언트를 손상시킬 미디어 유형을 변경해야하는 경우 새 클라이언트를 만들고 URL은 그대로 두십시오!
그리고 현재 내가 application / xml 및 application / json을 미디어 유형으로 사용하는 경우 이것이 의미가 없다고 말하는 독자들에게. 그것들을 어떻게 버전 화해야합니까? 넌 아니야. 이러한 미디어 유형은 코드 다운로드를 사용하여 구문 분석하지 않는 한 RESTful 인터페이스에 거의 쓸모가 없습니다.
아, 다시 낡은 심술 모자를 쓰고 있어요.
ReST 관점에서는 전혀 문제가되지 않습니다. 소시지가 아닙니다.
클라이언트는 따르려는 URI를 수신하고이를 불투명 한 문자열로 취급합니다. 원하는 것을 넣으면 클라이언트는 버전 식별자와 같은 것을 알지 못합니다 .
클라이언트가 알고있는 것은 미디어 유형을 처리 할 수 있다는 것입니다. Darrel의 조언을 따르는 것이 좋습니다. 또한 저는 개인적으로 편안한 아키텍처에서 사용되는 형식을 4 번 변경해야 심각한 문제를 일으킨다는 거대한 경고 신호를 가져오고 변경 복원력을 위해 미디어 유형을 디자인 할 필요성을 완전히 우회해야한다고 생각합니다.
그러나 어느 쪽이든 클라이언트는 이해할 수있는 형식의 문서 만 처리하고 그 안의 링크를 따라갈 수 있습니다. 링크 관계 (전환)에 대해 알아야합니다. 따라서 URI에있는 것은 완전히 관련이 없습니다.
개인적으로 http : // localhost / 3f3405d5-5984-4683-bf26-aca186d21c04에 투표합니다.
더 이상 클라이언트 개발자 나 시스템을 만지는 사람이 URI의 시작 부분이나 끝에 v4를 넣어야하는지 질문하는 것을 방지하는 완벽하게 유효한 식별자 (서버 관점에서 4 개가 없어야한다고 제안합니다. 버전, 4 가지 미디어 유형).
URL에 버전을 넣지 말고 요청의 Accept Header에 버전을 넣어야합니다.이 스레드에 대한 내 게시물을 참조하십시오.
URL에 버전을 고정하기 시작하면 http://company.com/api/v3.0/customer/123/v2.0/orders/4321/ 과 같은 어리석은 URL로 끝납니다 .
그리고 다른 문제도 많이 발생합니다. 내 블로그를 참조하세요. http://thereisnorightway.blogspot.com/2011/02/versioning-and-types-in-resthttp-api.html
REST API 버전 관리에 대한 다음 (덜 구체적인) SO 질문이 도움이 될 수 있습니다.
API 버전 관리에는 4 가지 접근 방식이 있습니다.
URI 경로에 버전 추가 :
http://example.com/api/v1/foo
http://example.com/api/v2/foo
주요 변경 사항이있는 경우 v1, v2, v3 ...과 같은 버전을 늘려야합니다.
다음과 같이 코드에서 컨트롤러를 구현할 수 있습니다.
@RestController
public class FooVersioningController {
@GetMapping("v1/foo")
public FooV1 fooV1() {
return new FooV1("firstname lastname");
}
@GetMapping("v2/foo")
public FooV2 fooV2() {
return new FooV2(new Name("firstname", "lastname"));
}
매개 변수 버전 관리 요청 :
http://example.com/api/v2/foo/param?version=1
http://example.com/api/v2/foo/param?version=2
버전 매개 변수는 API 사용 방법에 따라 선택 사항이거나 필수 일 수 있습니다.
구현은 다음과 유사 할 수 있습니다.
@GetMapping(value = "/foo/param", params = "version=1")
public FooV1 paramV1() {
return new FooV1("firstname lastname");
}
@GetMapping(value = "/foo/param", params = "version=2")
public FooV2 paramV2() {
return new FooV2(new Name("firstname", "lastname"));
}
사용자 정의 헤더 전달 :
http://localhost:8080/foo/produces
헤더 포함 :
headers[Accept=application/vnd.company.app-v1+json]
또는:
headers[Accept=application/vnd.company.app-v2+json]
이 체계의 가장 큰 장점은 대부분 의미 체계입니다. 버전 관리와 관련하여 URI를 복잡하게 만들지 않습니다.
가능한 구현 :
@GetMapping(value = "/foo/produces", produces = "application/vnd.company.app-v1+json")
public FooV1 producesV1() {
return new FooV1("firstname lastname");
}
@GetMapping(value = "/foo/produces", produces = "application/vnd.company.app-v2+json")
public FooV2 producesV2() {
return new FooV2(new Name("firstname", "lastname"));
}
호스트 이름 변경 또는 API 게이트웨이 사용 :
기본적으로 한 호스트 이름에서 다른 호스트 이름으로 API를 이동합니다. 이 빌드를 동일한 리소스에 대한 새 API를 호출 할 수도 있습니다.
또한 API 게이트웨이를 사용하여이 작업을 수행 할 수 있습니다.
버전이 지정된 API를 만들고 싶었고이 기사가 매우 유용하다는 것을 알았습니다.
http://blog.steveklabnik.com/posts/2011-07-03-nobody-understands-rest-or-http
"내 API의 버전을 지정하고 싶습니다"에 대한 작은 섹션이 있습니다. 간단하고 이해하기 쉬웠습니다. 핵심은 헤더의 Accept 필드를 사용하여 버전 정보를 전달하는 것입니다.
버전 관리에 URI를 사용하는 경우 버전 번호는 API 루트의 URI에 있어야 모든 리소스 식별자가이를 포함 할 수 있습니다.
기술적으로 REST API는 URL 변경으로 인해 중단되지 않습니다 (일관된 인터페이스 제약의 결과). 관련 의미 (예 : API 특정 RDF 어휘)가 이전 버전과 호환되지 않는 방식 (드물게)으로 변경되는 경우에만 중단됩니다. 현재 많은 ppl은 탐색을위한 링크 (HATEOAS 제약)와 vocab을 사용하여 REST 응답 (자체 설명 메시지 제약)을 주석 처리하지 않기 때문에 클라이언트가 중단됩니다.
사용자 정의 MIME 유형 및 MIME 유형 버전 관리는 관련 메타 데이터 및 표현 구조를 짧은 문자열에 넣는 것이 작동하지 않기 때문에 도움이되지 않습니다. Ofc. 메타 데이터와 구조가 자주 변경되므로 버전 번호도 ...
따라서 귀하의 질문에 답하기 위해 귀하의 요청과 응답에 어휘 ( Hydra , 연결된 데이터 ) 에 주석을 달고 버전 관리를 잊어 버리거나 이전 버전과 호환되지 않는 어휘 변경 (예 : 어휘를 다른 어휘 로 교체하려는 경우)에만 사용하십시오.