Reputation: 7217
I am writing a Web API and have defined a controller with various GET, POST methods etc. I am using Swagger Open API for my documentation and want to understand the correct way to annotate. Here's an example of a controller method I have:
/// <summary>Download a file based on its Id.</summary>
/// <param name="id">Identity of file to download.</param>
/// <returns><see cref="MyFile" /> file content found.</returns>
[HttpGet("download/{id}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[SwaggerResponse(200, "Myfile content", typeof(MyFile))]
[SwaggerResponse(404, "Could not find file", typeof(MyFile))]
public async Task<IActionResult> DownloadAsync(int id)
{
const string mimeType = "application/octet-stream";
var myFile = await _dbContext.MyFiles.FindAsync(id);
// If we cannot find the mapping, return 404.
if (myFile.IsNullOrDefault())
{
return NotFound();
}
// Download using file stream.
var downloadStream = await _blobStorage.DownloadBlob(myFile.FileLocation);
return new FileStreamResult(downloadStream, mimeType) { FileDownloadName = myFile.FileName };
}
As you can see, I'm using both ProducesResponseType and SwaggerResponse to describe the download method. I'm a bit confused as to the correct attribute to use - swagger response or produces response type? Should I use both? Why would I favor one over the other?
Thanks for any pointers in advance! :)
Upvotes: 4
Views: 13306
Reputation: 315
In my case I am already using "SwaggerOperation" annotation to add summary and description to the actions (and highly recommend that), that is why I went on using SwaggerResponse instead of ProducesResponseType anyway. At the end it really should not matter, you can see from source code that SwaggerResponseAttribute is derived from ProducesResponseTypeAttribute:
Upvotes: 3
Reputation: 3473
Using both ProducesResponseType
and SwaggerResponse
is not necessary.
It also depends on your action declaration, for example your action returs Task<IActionResult>
.
Knowing only that (without any additional attributes) a return type from that action might be anything.
So by adding: [SwaggerResponse(200, "Myfile content", typeof(MyFile))]
attribute to that method, the type MyFile
is known to be returned from that action and can be documented.
On the other hand you wouldn't need that attribute if you specified that in return type as follows:
[HttpGet("download/{id}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<MyFile>> DownloadAsync(int id)
I got rid of 2 SwaggerResponse
attributes and the documented return type of this action will still be the same.
I would say the less annotation the better, but of course it depends on your needs ;p
Upvotes: 5