REST URI의 버전을 지정하는 방법


111

REST URI를 버전 화하는 가장 좋은 방법은 무엇입니까? 현재 URI 자체에 버전 #이 있습니다.

http://example.com/users/v4/1234/

이 표현의 버전 4 용.

버전이 queryString에 속합니까? 즉.

http://example.com/users/1234?version=4

아니면 버전 관리가 다른 방법으로 가장 잘 수행됩니까?


답변:


34

v4가 v3과 다른 리소스를 식별하기 때문에 URI 자체 (옵션 1)의 일부로 만드는 것이 가장 좋습니다. 두 번째 옵션과 같은 쿼리 매개 변수 는 리소스가 아닌 요청 과 관련된 추가 (쿼리) 정보를 전달하는 데 가장 잘 사용할 수 있습니다 .


11
문제는 우리가 논의하는 다른 리소스입니까? 아니면 해당 리소스의 다른 표현입니까? REST는 표현과 자원을 구별합니까?
Cheeso

1
@Cheeso-OP는 다른 리소스가 아닌 다른 표현임을 나타내므로 내 대답입니다.
Greg Beech


"두 번째 옵션과 같은 쿼리 매개 변수는 리소스가 아닌 요청과 관련된 추가 (쿼리) 정보를 전달하는 데 가장 잘 사용될 수 있습니다."에 대한 +1
andy

다른 표현의 경우 "Accept"와 같은 헤더를 사용해야한다고 생각합니다. 그러면 클라이언트는 "I accept only version 4"서버에 지정할 수 있으며 서버는 해당 표현으로 응답 할 수 있습니다. 수락이 전송되지 않으면 마지막 버전이 제공됩니다.
카를로스 악단

190

URL을 버전 화하지 마십시오.

  • 당신은 영구 링크를 끊습니다
  • URL 변경은 인터페이스를 통해 질병처럼 퍼질 것입니다. 변경되지 않았지만 변경된 표현을 가리키는 표현으로 무엇을합니까? URL을 변경하면 이전 클라이언트가 손상됩니다. 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 인터페이스에 거의 쓸모가 없습니다.


66
글 머리 기호를 해결합니다. 1. 영구 링크는 특정 버전에 연결되기 때문에 영구 링크를 끊지 않습니다. 2. 모든 버전이 문제가되지 않는 버전으로되어있는 경우. 이전 URL은 계속 작동 할 수 있습니다. 이상적으로는 버전 3 리소스에 대한 연결을 반환하는 버전 4 URL이 필요하지 않습니다. 3. 아마도
Mike Pone 2009-06-11

10
웹 브라우저의 새 버전으로 업그레이드했을 때 즐겨 찾기에 추가 된 모든 즐겨 찾기가 손상되었다고 상상해보십시오! 개념적으로 사용자는 리소스 표현 버전이 아니라 리소스에 대한 링크를 저장한다는 점을 기억하십시오.
Darrel Miller

11
@Gili REST API가 자체 설명 적이어야한다는 요구 사항을 충족하려면 콘텐츠 유형 헤더가 메시지의 완전한 의미 설명을 제공해야합니다. 즉, 미디어 유형은 데이터 계약입니다. application / xml 또는 application / json을 제공하는 경우 해당 XML / Json에 포함 된 내용에 대해 클라이언트에 알리지 않습니다. 클라이언트 애플리케이션이 메시지에없는 정보를 기반으로 커플 링을 작성하는 / Customer / Name을 끌어내는 순간. 대역 외 결합을 제거하는 것은 RESTfulness를 달성하는 데 중요합니다.
Darrel Miller

6
@Gili 클라이언트는 루트 URL 외에 API의 URL에 대한 사전 지식이 없어야합니다. 표현 형식을 특정 URL에 연결해서는 안됩니다. 미디어 유형을 선택할 때는 application / vnd.mycompany.myformat + xml과 같은 특정 형식이나 XHtml, Atom, RDF 등과 같은 표준화 된 형식 중에서 선택해야합니다.
Darrel Miller

4
API 버전을 별도의 헤더 필드에 넣는 것이 합리적입니까? 다음과 같이 수락 : application / com.example.myapp + json; version = 1.0
Erik

21

아, 다시 낡은 심술 모자를 쓰고 있어요.

ReST 관점에서는 전혀 문제가되지 않습니다. 소시지가 아닙니다.

클라이언트는 따르려는 URI를 수신하고이를 불투명 한 문자열로 취급합니다. 원하는 것을 넣으면 클라이언트는 버전 식별자와 같은 것을 알지 못합니다 .

클라이언트가 알고있는 것은 미디어 유형을 처리 할 수 ​​있다는 것입니다. Darrel의 조언을 따르는 것이 좋습니다. 또한 저는 개인적으로 편안한 아키텍처에서 사용되는 형식을 4 번 변경해야 심각한 문제를 일으킨다는 거대한 경고 신호를 가져오고 변경 복원력을 위해 미디어 유형을 디자인 할 필요성을 완전히 우회해야한다고 생각합니다.

그러나 어느 쪽이든 클라이언트는 이해할 수있는 형식의 문서 만 처리하고 그 안의 링크를 따라갈 수 있습니다. 링크 관계 (전환)에 대해 알아야합니다. 따라서 URI에있는 것은 완전히 관련이 없습니다.

개인적으로 http : // localhost / 3f3405d5-5984-4683-bf26-aca186d21c04에 투표합니다.

더 이상 클라이언트 개발자 나 시스템을 만지는 사람이 URI의 시작 부분이나 끝에 v4를 넣어야하는지 질문하는 것을 방지하는 완벽하게 유효한 식별자 (서버 관점에서 4 개가 없어야한다고 제안합니다. 버전, 4 가지 미디어 유형).


표현이 크게 변경되어야하고 이전 버전과 호환되지 않는 경우 어떻게해야합니까?
Mike Pone

1
네임 스페이스 및 확장 가능한 xsd 또는 기존 xml 형식 (예 : atom)을 사용하는 것과 같이 확장 가능한 방식으로 미디어 유형을 디자인함으로써이를 방지 할 수 있어야합니다. 정말로 필요하다면 다른 미디어 유형이 갈 길입니다.
SerialSeb

1
나는이 완전히 유효한 대답을 좋아하지만 제안 된 URI는 '해킹 가능한'URI를 원하는 실제 시나리오보다 요점을 더 잘 보여줍니다.
Dave Van den Eynde

10

URL에 버전을 넣지 말고 요청의 Accept Header에 버전을 넣어야합니다.이 스레드에 대한 내 게시물을 참조하십시오.

API 버전 관리에 대한 모범 사례?

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


11
미안하지만 이런 어리석은 URL로 끝나지 않을 것 같습니다. 특정 리소스에 버전 번호를 연결하거나 특정 표현에 (더 나쁘게) 묶고 있습니다. 그것은 어리석은 것입니다, IMO. 오히려 API의 버전을 관리하므로 URI에 두 개 이상의 버전이있을 수 없습니다.
fool4jesus 2013


3

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 게이트웨이를 사용하여이 작업을 수행 할 수 있습니다.


2

REST 서비스를 사용하기 전에 인증이 필요한 경우 API 키 / 토큰을 API 버전과 쉽게 연결하고 내부적으로 라우팅을 수행 할 수 있습니다. 새 버전의 API를 사용하려면 해당 버전에 연결된 새 API 키가 필요할 수 있습니다.

불행히도이 솔루션은 인증 기반 API에서만 작동합니다. 그러나 URI에서 버전을 유지합니다.



1

URI 끝에 옵션 값으로 버전을 포함합니다. / V4와 같은 접미사 또는 설명 된 쿼리 매개 변수가 될 수 있습니다. 두 변형을 모두 지원하도록 / V4를 쿼리 매개 변수로 리디렉션 할 수도 있습니다.


1

버전 관리에 URI를 사용하는 경우 버전 번호는 API 루트의 URI에 있어야 모든 리소스 식별자가이를 포함 할 수 있습니다.

기술적으로 REST API는 URL 변경으로 인해 중단되지 않습니다 (일관된 인터페이스 제약의 결과). 관련 의미 (예 : API 특정 RDF 어휘)가 이전 버전과 호환되지 않는 방식 (드물게)으로 변경되는 경우에만 중단됩니다. 현재 많은 ppl은 탐색을위한 링크 (HATEOAS 제약)와 vocab을 사용하여 REST 응답 (자체 설명 메시지 제약)을 주석 처리하지 않기 때문에 클라이언트가 중단됩니다.

사용자 정의 MIME 유형 및 MIME 유형 버전 관리는 관련 메타 데이터 및 표현 구조를 짧은 문자열에 넣는 것이 작동하지 않기 때문에 도움이되지 않습니다. Ofc. 메타 데이터와 구조가 자주 변경되므로 버전 번호도 ...

따라서 귀하의 질문에 답하기 위해 귀하의 요청과 응답에 어휘 ( Hydra , 연결된 데이터 ) 에 주석을 달고 버전 관리를 잊어 버리거나 이전 버전과 호환되지 않는 어휘 변경 (예 : 어휘를 다른 어휘 로 교체하려는 경우)에만 사용하십시오.


0

URL이 아닌 MIME 형식으로이 작업을 수행하는 데 투표합니다. 하지만 그 이유는 다른 사람들과 같지 않습니다.

고유 한 리소스를 찾기 위해 URL이 고유해야한다고 생각합니다 (해당 리디렉션 제외). 당신이 동의한다면, /v2.0URL을에, 왜 아닙니다 /ver2.0또는 /v2//v2.0.0? 심지어 -alpha-beta? (그러면 완전히 semver 의 개념이 됩니다 )

따라서 MIME 유형의 버전이 URL보다 더 적합합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.