使用 swagger 產生 相關的 api document 與 sample
環境 .net framework 4.7.2
Nuget 安裝
1. Swashbuckle (安裝完會產生SwaggerConfig.cs)
2. Swashbuckle.Core 5.6.0
3. Swashbuckle.Examples 4.0.0
調整 SwaggerConfig.cs
1. 將 c.IncludeXmlComments(GetXmlCommentsPath()); 反註解掉
2. 設定 project 輸出路徑為 App_Data\SwaggerApi.xml
3. 新增 GetXmlCommentsPath 私有方法
private static string GetXmlCommentsPath()
{
return Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, @"App_Data\SwaggerApi.xml");
}
新增 ValuesController 進行測試
public class ValuesController : ApiController
{
/// <summary>
/// api index page
/// </summary>
/// <returns></returns>
[SwaggerResponse(HttpStatusCode.OK, "成功", typeof(string))]
[SwaggerResponse(HttpStatusCode.NoContent, "沒有資料", typeof(void))]
[SwaggerResponse(HttpStatusCode.InternalServerError, "內部錯誤", typeof(ResponseModel))]
[HttpGet]
[Route("Index")]
public string Index()
{
return "Welcome api home";
}
/// <summary>
/// Custom Action by demo purpose
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost]
[Route("CustomAction")]
public ResponseModel CustomAction([FromBody] RequestModel request)
{
return new ResponseModel()
{
Message = $"{request.Name}:{request.Age}",
StatusCode = HttpStatusCode.OK.GetHashCode()
};
}
}
相關Model 如下
public class RequestModel
{
public int Age { set; get; }
public string Name { set; get; }
}
public class ResponseModel
{
public string Message { get; set; }
public int StatusCode {get; set; }
}
裡面的內容就會包含了 200, 204, 500 的各種說明,甚至裡面的 response model 也特別設成不一樣的
然而這邊的 example value 都是空的,如果我們希望做一個 sample 給讀 spec 的人呢?
增加 example
1. 確認在上列步驟已經安裝了 Swashbuckle.Examples 4.0.0
2. 打開 SwaggerConfig.cs 將 c.OperationFilter<AddDefaultResponse>(); 反註解掉
並改為 c.OperationFilter<ExamplesOperationFilter>();
3. 建立 example model
public class RequestExampleModel : IExamplesProvider
{
public object GetExamples()
{
return new RequestModel
{
Name = "Ace",
Age = 99
};
}
}
public class ResponseExampleModel : IExamplesProvider
{
public object GetExamples()
{
return new ResponseModel
{
Message = "Example Message",
StatusCode = 200
};
}
}
將 swgger example 的 attribute 掛上相對應的 action
/// <summary>
/// Custom Action by demo purpose
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[Route("CustomAction")]
[HttpPost]
[SwaggerRequestExample(
typeof(RequestModel),
typeof(RequestExampleModel))]
[SwaggerResponseExample(HttpStatusCode.OK,
typeof(ResponseExampleModel))]
public ResponseModel CustomAction([FromBody] RequestModel request)
{
return new ResponseModel()
{
Message = $"{request.Name}:{request.Age}",
StatusCode = HttpStatusCode.OK.GetHashCode()
};
}
這邊的 request 與 response 就會有相對應的 example 了,有助其他人看文件更快可以了解 sample 裡的資料所代表的意義
如果有仔細看的話,會發現 example 上面會有 "application/json" 的資料,導致 sample 格式會略有不同
在搜尋的時候發現這個 issue 已經 closed 了,把 swagger-ui 改成 v3 就能解決,但改了還是沒有解決
翻了 Swashbuckle.Examples 的 source code 後會發現問題所在
Request 時 media type 設成 false
Response 時 media type 設為 true
這也能解釋為什麼 request 時沒有 application/json ,但 response 卻會有
參考資料
https://dotblogs.com.tw/yc421206/2019/01/23/tips_write_write_web_api_document_via_swagger
https://github.com/mattfrear/Swashbuckle.Examples
https://github.com/esi/esi-issues/issues/438
https://github.com/mattfrear/Swashbuckle.Examples/blob/master/Swashbuckle.Examples/Examples/ExamplesOperationFilter.cs