ASP.NET Core Web APIバージョン管理

16329 ワード

nuget.orgではMicrosoftを見つけることができます.AspNetCore.Mvc.Versioningパッケージでは、Web APIのエンドポイントをバージョン化する方法に関する詳細なオプションを提供します.このパッケージの利点は、コントローラでパラメータ付きのプロパティを直接使用できるため、非常に便利です.
もう1つの利点は、呼び出しを試みたバージョンがサポートされていないことをクライアントに報告することです.スタータープでcsクラスにversionignサービスを追加する場合は、このオプションを有効にするだけです.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.AddApiVersioning(o => o.ReportApiVersions = true);
        }

APIのバージョン管理を開始したばかりで、まだバージョンIDがない場合は、デフォルトのバージョン管理を設定することもできます.バージョン管理データのないすべてのリクエスト
 public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.AddApiVersioning(o =>
            {
                o.ReportApiVersions = true;
                o.AssumeDefaultVersionWhenUnspecified = true;
                o.DefaultApiVersion = new ApiVersion(1,0);
            });
        }
    

に注意
デフォルトのバージョンがコントローラに破棄されたとマークされていないことを確認し、クライアント呼び出しがコントローラのバージョン管理プロパティによって宣言されたバージョン管理ポリシーによって拒否されないことを確認します.
異なるバージョンの制御オプションのコードの例と設定から始めましょう.実際には、これらがすべてそうであることを見てみましょう.
パラメータベースのバージョン管理
オープンボックスはクエリー文字列バージョン管理をサポートするため、api-version=1.0を送信することで、アプリケーションにバージョン属性1.0でコントローラにルーティングするように伝えます.
namespace Core.Versioning.Sample.Controllers
{

    [ApiVersion("1.0")]
    [Route("api/[controller]")]
    public class ValueController : Controller
    {
        [HttpGet]
        public String Get()
        {
            return "Version 1.0";
        }
    }
}
    

新しいバージョンを追加するには、ApiVersionプロパティを持つ異なるネーミングスペースで同じコントローラ名を新しいバージョンに追加できます.
namespace Core.Versioning.Sample.Controllers.v2
{

    [ApiVersion("2.0")]
    [ApiVersion("1.0", Deprecated = true)]
    [Route("api/[controller]")]
    public class ValueController : Controller
    {
        [HttpGet]
        public String Get()
        {
            return "Version 2.0";
        }
    }
}

次に、異なるapi-versionパラメータ値の応答をテストします.
$ curl http://localhost:5000/api/value?api-version = 1.0 -i 
HTTP/1.1 200 OK日付:木曜日、2018年6月14日08:11:13 GMT内容タイプ:text/plain;charset=utf-8サーバ:Kestrel Transfer-Encoding:chunked api-supported-versions:1.0,2.0 Version 1.0
2.0バージョンでは、応答が異なります.
$ curl http://localhost:5000/api/value?api-version = 2.0 -i 
HTTP/1.1 200 OK 
日付:木曜日、2018年6月14日08:11:19 GMT
コンテンツタイプ:text/plain; charset = utf-8 
サーバ:Kestrel
Transfer-Encoding:chunked 
api-supported-versions:1.0,2.0 
サポートされていないバージョン3.0を使用してAPIを呼び出してみます.このような状況で何が起こるか見てみましょう
$ curl http://localhost:5000/api/value?api-version = 3.0 -i 
HTTP/1.1 400 Bad Request 
Date:Thu,14 Jun 2018 08:16:12 GMT 
Content-Type:application/json; charset = utf-8 
サーバ:Kestrel
Transfer-Encoding:chunked 
api-supported-versions:1.0,2.0 
{   
   “error”:{   
      “code”:“UnsupportedApiVersion”, 
「メッセージ」:「要求URIに一致するHTTPリソース」http://localhost:5000/api/value?api-version=3.0'はAPIバージョン'3.0'をサポートしていません.“, 
      ”innerError“:null 
   } 
}
応答コードは200 OKではありませんが、400 Bad Request with JSONメッセージはこのバージョンがサポートされていないことを示しています.
タイトルベースのバージョン管理
バージョンをクエリー文字列値としてWeb APIエンドポイントに送信するのが不十分な場合は、ヘッダーを使用します.このバージョンの制御方法については、Startup.csファイルでは、バージョン制御パッケージが特定のキーのヘッダでバージョン値を検索することを通知するために、いくつかの小さな変更が行われます.api-versionで使用したクエリー文字列と同じ方法を選択しました
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.AddApiVersioning(o =>
            {
                o.ReportApiVersions = true;
                o.AssumeDefaultVersionWhenUnspecified = true;
                o.DefaultApiVersion = new ApiVersion(1,0);
                o.ApiVersionReader = new HeaderApiVersionReader(“api-version”);
            });
        }
    

リクエストヘッダにapi-version値を追加することで、POSTMANを使用して簡単にテストできます.この方法では、常に異なるリクエストヘッダ値を持つ同じエンドポイントURLを使用して、異なるバージョンのエンドポイントにアクセスします.
これが有効であることを確認するために、タイトルに2.0バージョンのAPIを呼び出します.
$ curl --header“api-version:2.0”http://localhost:5000/api/value -i 
HTTP/1.1 200 OK 
日付:木曜日、2018年6月14日08:27:49 GMT
コンテンツタイプ:text/plain; charset = utf-8 
サーバ:Kestrel
Transfer-Encoding:chunked 
api-supported-versions:1.0,2.0 
Version 2.0 
ルーティングベースのバージョン管理
ルーティングベースのバージョンは、コントローラベースのurl構造を制御し、ルーティングにバージョンが含まれることが望ましい.そのためにはStartupをcsはタイトルから読み出さずにURLを表示するように変更しました
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.AddApiVersioning(o =>
            {
                o.ReportApiVersions = true;
                o.AssumeDefaultVersionWhenUnspecified = true;
                o.DefaultApiVersion = new ApiVersion(1,0);
                o.ApiVersionReader = new UrlSegmentApiVersionReader();
            });
        }

1.0に設定したデフォルトバージョンをサポートするには、バージョンセグメントのない特定のバージョンに追加のルーティングを提供する必要があります.そうしないと、デフォルトバージョンは機能しません.
public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.AddApiVersioning(o =>
            {
                o.ReportApiVersions = true;
                o.AssumeDefaultVersionWhenUnspecified = true;
                o.DefaultApiVersion = new ApiVersion(1, 0);
                o.ApiVersionReader = new HeaderApiVersionReader("api-version");
            });
        }
    

ここでLamondLuのブログに感謝します.HeaderApiVersionReaderはすでに淘汰されています.以下のコードが必要です.
services.AddApiVersioning(
    o => o.ApiVersionReader = ApiVersionReader.Combine(
        new QueryStringApiVersionReader(),
        new HeaderApiVersionReader()
        {
            Headers = { "api-version" }
        } ) );

リクエストヘッダにapi-version値を追加することで、POSTMANを使用して簡単にテストできます.この方法では、常に異なるリクエストヘッダ値を持つ同じエンドポイントURLを使用して、異なるバージョンのエンドポイントにアクセスします.
これが有効であることを確認するために、タイトルに2.0バージョンのAPIを呼び出します.
$ curl --header“api-version:2.0”http://localhost:5000/api/value -i 
HTTP/1.1 200 OK 
日付:木曜日、2018年6月14日08:27:49 GMT
コンテンツタイプ:text/plain; charset = utf-8 
サーバ:Kestrel
Transfer-Encoding:chunked 
api-supported-versions:1.0,2.0 
Version 2.0 
ルーティングベースのバージョン管理
ルーティングベースのバージョンは、コントローラベースのurl構造を制御し、ルーティングにバージョンが含まれることが望ましい.そのためにはStartupをcsはタイトルから読み出さずにURLを表示するように変更しました
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.AddApiVersioning(o =>
            {
                o.ReportApiVersions = true;
                o.AssumeDefaultVersionWhenUnspecified = true;
                o.DefaultApiVersion = new ApiVersion(1,0);
                o.ApiVersionReader = new UrlSegmentApiVersionReader();
            });
        }
    

1.0に設定したデフォルトバージョンをサポートするには、バージョンセグメントのない特定のバージョンに追加のルーティングを提供する必要があります.そうしないと、デフォルトバージョンは機能しません.
namespace Core.Versioning.Sample.Controllers
{

    [ApiVersion("1.0")]
    [ApiVersion("1.0", Deprecated = true)]
    [Route("api/[controller]")]
    [Route("api/v{version:apiVersion}/[controller]")]
    public class ValueController : Controller
    {
        [HttpGet]
        public String Get()
        {
            return "Version 1.0";
        }
    }
}

namespace Core.Versioning.Sample.Controllers.v2
{

    [ApiVersion("2.0")]
    [Route("api/v{version:apiVersion}/[controller]")]
    public class ValueController : Controller
    {
        [HttpGet]
        public String Get()
        {
            return "Version 2.0";
        }
    }
}
    

ではcurlで応答を確認しましょう
$ curl http://localhost:5000/api/value -i 
HTTP/1.1 200 OK 
日付:木曜日、2018年6月14日08:03:34 GMT
コンテンツタイプ:text/plain; charset = utf-8 
サーバ:Kestrel
Transfer-Encoding:chunked 
api-supported-versions: 
1.0,2.0 api-deprecated-versions:1.0 
Version 1.0 
応答にapi-deprecated-vesionヘッダキーが1.0に設定されていることに気づくかもしれません.これは、新しいコントローラに次のプロパティがあるためです.
ApiVersion(“1.0”,Deprecated = true)
    

これは、Web APIクライアントが1.0版をサポートしていないことを示しています.これは、RESTサービスが異なるベンダーから複数の異なるクライアントをサポートしている場合に便利です.