6

うまくいけば、誰かが MVC 6 と Swagger のバージョン管理された API で同様のことを試して、さまざまなバージョンに関するドキュメントを表示したことでしょう。

この ASP.NET 5 リポジトリに従って、MVC 6 で推奨される API バージョン管理を使用しています。私が行った唯一の変更は、リクエストのカスタム http ヘッダーから API バージョンを読み取る GetVersion メソッドです。

//in VersionRangeValidator.cs
public static string GetVersion(HttpRequest request)
{
        //return request.Query["version"];
        if (!string.IsNullOrWhiteSpace(request.Headers[Constants.CommonRoutingDefinitions.ApiVersionSegmentName]))
        {
            return request.Headers[Constants.CommonRoutingDefinitions.ApiVersionSegmentName];
        }
        return Constants.CommonRoutingDefinitions.CurrentApiVersion;
 }

そして、私は次のようなコントローラーを持っています:

[Route("api/[controller]")]
[Produces(Constants.MediaTypeNames.ApplicationJson)]
public class TagsController : Controller
{
    private readonly ITagService _tagService;

    public TagsController(ITagService tagService)
    {
        _tagService = tagService;
    }

    /// <summary>
    /// Version 1 by default
    /// </summary>
    /// <returns>All the tags</returns>
    [HttpGet]
    [Produces(typeof(IEnumerable<Tag>))]
    public IEnumerable<Tag> GetTags()
    {
        IEnumerable<Tag> tags = _tagService.GetTags();
        return tags;
    }

    /// <summary>
    /// Version 2
    /// </summary>
    /// <returns>All the tags V2</returns>
    [VersionGet("", versionRange: "[2]")]
    public IEnumerable<Tag> GetTagsV2()
    {
        IList<Tag> tags = new List<Tag>
        {
            new Tag { Id = 1, Links = Enumerable.Empty<Link>().ToList(), Name = "Tag version 2" }
        };
        return tags;
    }
}

バージョニングはカスタム http ヘッダーで行われるため、

/api/tags を取得

コンテンツ タイプ: アプリケーション/json

ヘッダーが指定されていないため、デフォルトで GetTags() アクションがヒットし、

/api/tags を取得

API バージョン: 2

コンテンツ タイプ: アプリケーション/json

GetTagsV2() アクションにヒットします。

このブログの手順に従って Swagger UI と Swagger GEN ライブラリを追加したので、project.json次の依存関係があります。

"Swashbuckle.SwaggerGen": "6.0.0-rc1-final",
"Swashbuckle.SwaggerUi": "6.0.0-rc1-final"

次に、Startup.cs で Swagger をパイプラインに追加します。

 //inside Configure(IApplicationBuilder app)
 app.UseSwaggerGen();
 app.UseSwaggerUi();

Swagger を次のように構成します。

private void ConfigureSwagger(IServiceCollection services)
{
        services.AddSwaggerGen();

        services.ConfigureSwaggerDocument(options =>
        {
            options.MultipleApiVersions(new Swashbuckle.SwaggerGen.Info[]
            {
                new Swashbuckle.SwaggerGen.Info
                {
                    Version = "v1",
                    Title = "MyApp API",
                    Description = "A RESTful API"
                },
                new Swashbuckle.SwaggerGen.Info
                {
                    Version = "v2",
                    Title = "MyApp API (v2)",
                    Description = "A RESTful API"
                }
            }, (description, version) => {
                //description is an instance of ApiDescription and 
                //version is either "v1" or "v2" 
                //depending on the user choice in swagger UI page
                //TODO, how can I know whether the action belongs to v1 or to v2 to return true or false as appropriate?
            });
            options.OperationFilter(new Swashbuckle.SwaggerGen.XmlComments.ApplyXmlActionComments(Configuration["Documentation:SwaggerDocXml"]));
        });

        services.ConfigureSwaggerSchema(options =>
        {
            options.DescribeAllEnumsAsStrings = true;
            options.ModelFilter(new Swashbuckle.SwaggerGen.XmlComments.ApplyXmlTypeComments(Configuration["Documentation:SwaggerDocXml"]));
        });
}

問題は、説明(Microsoft.AspNet.Mvc.ApiExplorer.ApiDescription のインスタンス)から、特定のアクションを Swagger UI に表示する必要があるかどうかを知るために必要な情報を取得する方法がわからないことです。指定されたバージョンで。どんなヒントでも大歓迎です。この ASP.NET 5 リポジトリのバージョン管理の実装がどのように機能するかを理解するのに役立ちます。なぜなら、私はまだそれをよく理解しておらず、アクションの制約がどのように機能するかについての適切な説明を見つけることができないからです。

PS:このスタックオーバーフローの質問は、MVC 6 でバージョン管理を実装するのに役立ちましたが、Swagger が API のバージョン管理のこの方法とどのように統合されるかについてはあまりわかりませんでした。

4

2 に答える 2

2

ここでの質問に対する私の最初の回答です。お役に立てば幸いです。コード スニペットの形式が悪いことをお詫びしますが、今はほとんど時間がありません。

あなたはほとんどそこにいましたが、説明にバージョンのフィルターを追加しませんでした. これは、次の URL 形式の実装で機能します。

"/v1/Sessions" and "/v3/Sessions"


options.MultipleApiVersions(new Info[]{
new Info
{
        Version = "v1",
        Title = "your_own",
        Description = "Defines the API to access... your_own",
        TermsOfService = "your_own",
        Contact = new Contact()
        {
            Email = "your_own",
            Name = "your_own"
        }
},
new Info
    {
        Version = "v3",
        Title = "your_own",
        Description =
            "Defines the API to .... your_own",
        TermsOfService = "your_own",
        Contact = new Contact()
        {
            Email = "your_own",
            Name = "your_own"
        }
    }}, (description, version) => {
//Here we compare if the version is part of the incoming URI, if yes, show it on swagger page.
return description.RelativePath.ToLower().Contains(version.ToLower()); } );
于 2016-10-04T14:51:13.887 に答える
2

カスタムVersionGet属性があるようです。これを使用して、v2 エンドポイントを決定できます。他のエンドポイントはデフォルトで v1 になる場合があります (これが必要な場合)。

これが私が使用するスニペットです。カスタム属性の名前がApiVersion2.

public static bool ResolveVersion(ApiDescription apiDesc, string targetApiVersion)
{
    if (targetApiVersion == "v2")
    {
        ApiVersion2Attribute v2Attr = apiDesc.ActionDescriptor.GetCustomAttributes<ApiVersion2Attribute>().FirstOrDefault();
        if (v2Attr != null)
            return true;
    }

    if (targetApiVersion == "v1")
        return true;

    throw new NotSupportedException();
}
于 2017-01-12T10:24:18.113 に答える