APIでバージョンを呼び出す内容によって異なります。エンティティのさまざまな表現(xml、jsonなど)に対してバージョンを呼び出す場合は、acceptヘッダーまたはカスタムヘッダーを使用する必要があります。これが、httpが表現を操作するために設計された方法です。同じリソースを同時に呼び出して異なる表現を要求した場合、返されるエンティティはまったく同じ情報とプロパティ構造を持ちますが、形式が異なるため、この種のバージョン管理は表面的なものであるため、RESTfulです。
一方、「バージョン」をエンティティ構造の変更として理解している場合、たとえば、「ユーザー」エンティティに「年齢」フィールドを追加します。次に、リソースの観点からこれにアプローチする必要があります。これは、私の意見ではRESTfulアプローチです。Roy Fieldingが彼の論文で説明したように、RESTリソースは識別子からエンティティのセットへのマッピングです...したがって、エンティティの構造を変更するときは、それを指す適切なリソースが必要であることは理にかなっています。バージョン。この種のバージョン管理は構造的です。
私は次の場所で同様のコメントをしました:http://codebetter.com/howarddierking/2012/11/09/versioning-restful-services/
URLのバージョン管理を使用する場合、バージョンはURLの前ではなく、後になる必要があります。
GET/DELETE/PUT onlinemall.com/grocery-store/customer/v1/{id}
POST onlinemall.com/grocery-store/customer/v1
よりクリーンな方法でそれを行う別の方法ですが、実装時に問題が発生する可能性があります。
GET/DELETE/PUT onlinemall.com/grocery-store/customer.v1/{id}
POST onlinemall.com/grocery-store/customer.v1
このようにすることで、クライアントは、必要なエンティティにマップする必要なリソースを具体的に要求できます。実稼働環境で実装するときに本当に問題となるヘッダーやカスタムメディアタイプをいじる必要はありません。
また、URLをURLの後半に配置すると、クライアントは、メソッドレベルであっても、必要なリソースを具体的に選択するときに、より細かく設定できます。
しかし、開発者の観点から最も重要なことは、すべてのリソースとメソッドへのすべてのバージョンのマッピング(パス)全体を維持する必要がないことです。これは、サブリソース(埋め込みリソース)がたくさんある場合に非常に役立ちます。
実装の観点からは、リソースのレベルでそれを使用することは、たとえば、Jersey / JAX-RSを使用する場合、非常に簡単に実装できます。
@Path("/customer")
public class CustomerResource {
...
@GET
@Path("/v{version}/{id}")
public IDto getCustomer(@PathParam("version") String version, @PathParam("id") String id) {
return locateVersion(version, customerService.findCustomer(id));
}
...
@POST
@Path("/v1")
@Consumes(MediaType.APPLICATION_JSON)
public IDto insertCustomerV1(CustomerV1Dto customer) {
return customerService.createCustomer(customer);
}
@POST
@Path("/v2")
@Consumes(MediaType.APPLICATION_JSON)
public IDto insertCustomerV2(CustomerV2Dto customer) {
return customerService.createCustomer(customer);
}
...
}
IDtoは、ポリモーフィックオブジェクトを返すための単なるインターフェイスであり、CustomerV1とCustomerV2はそのインターフェイスを実装します。