Rob
Rob

Reputation: 7217

ASP.net Core Web API - correct swagger annotations

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

Answers (2)

ruzgarustu
ruzgarustu

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:

enter image description here

Upvotes: 3

Jakub Kozera
Jakub Kozera

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

Related Questions