I am creating a set of API's for the first time. Here's one of the methods:
// GET: api/Doors/0 /// <summary> /// Get a list of all doors for a given organization. /// </summary> /// <param name="organizationSys">The Organization ID for which all doors should be retreived.</param> /// <returns></returns> [Route("{organizationSys:int}")] public IHttpActionResult Get(int organizationSys) { try { Dictionary<string, object> parameters = new Dictionary<string, object>(); parameters.Add("@OrganizationSys", organizationSys); List<Door> doors = Repository<Doors>.GetList("WHERE OrganizationSys = @OrganizationSys", parameters).ToList(); if (doors == null || doors.Count() == 0) return Content(HttpStatusCode.NotFound, RejectionMessage.NoItemsFound); return Ok(doors); } catch (Exception ex) { return Content(HttpStatusCode.BadRequest, ex.Message); } }
I've set up a Unit Test to this endpoint, and it works perfectly. However, I do have one question.
In Swagger, I'd like to show an example of the data object that will be returned. The only return type on the method is IHttpActionResult
so I'm not surprised it's not showing the data model in Swagger. So, what do I need to change with this method so that the return object (in this case List<Door>
) will be more visible?
Does Swashbuckle support this?
Thanks!
A response is defined by its HTTP status code and the data returned in the response body and/or headers.
The annotation may be used to define a Schema for a set of elements of the OpenAPI spec, and/or to define additional properties for the schema. It is applicable e.g. to parameters, schema classes (aka "models"), properties of such models, request and response content, header.
1 - Open the Properties dialog for your project, click the "Build" tab and ensure that "XML documentation file" is checked. This will produce a file containing all XML comments at build-time. At this point, any classes or methods that are NOT annotated with XML comments will trigger a build warning.
That should be pretty straightforward:
[Route("{organizationSys:int}")] [ProducesResponseType(typeof(List<Door>), 200)] [ProducesResponseType(typeof(string), 400)] public IHttpActionResult Get(int organizationSys)
Note that since you have 2 exit points: one normal return with data, and a catch that returns error message, I've defined in the example above two possible result types:
List<Door>
string
Swashbuckle Swagger infrastructure will read that and provide very rough examples of the data for these cases.
However, if you need more detailed examples (i.e. with some reasonable field values) then you will have to implement so-called "example provider". See here for details and quick tutorial, in short:
[SwaggerRequestExample(typeof(DeliveryOptionsSearchModel), typeof(DeliveryOptionsSearchModelExample))] public async Task<IHttpActionResult> DeliveryOptionsForAddress(DeliveryOptionsSearchModel search)
and
public class DeliveryOptionsSearchModelExample : IExamplesProvider { public object GetExamples() { return new DeliveryOptionsSearchModel { Lang = "en-GB", Currency = "GBP", Address = new AddressModel { Address1 = "1 Gwalior Road", Locality = "London", Country = "GB", PostalCode = "SW15 1NP" }, Items = new[] { new ItemModel { ItemId = "ABCD", ItemType = ItemType.Product, Price = 20, Quantity = 1, RestrictedCountries = new[] { "US" } } } }; }
The example provider works in a really simple way: whatever the provider returns, it is serialized to JSON and returned as the example for given data type. Just like that.
Now, if your method returned DeliveryOptionsSearchModel
, the provider would use this data above directly.
Or, if your method returned a larger object, composed of DeliveryOptionsSearchModel
and few others, then Swagger would use this provider for one part of the response example, and other provider(s) (or default rough examples) for all other parts of the large object.
All of the above was for Net Core.
If you use 'normal' Net 4.5/4.6/4.7, then this way is not available, as the Attribute class does not exist. In AspMvc for Net 4.x there's only [ResponseType(typeof(..))]
attribute that allows to define a single return type. That's OK for most of the times. However, if you really need to differentiate return types over response codes, or if you need to provide good examples, that's a problem.
However! Some good people solved that already. See this article. It describes NuGet Swagger.Examples
, I believe it's for non-core, and it aims at providing better result descriptions.
It defines another attribute - [SwaggerResponse(HttpStatusCode.OK, Type=typeof(IEnumerable...
to define possible result codes and result types and provides plugin for Swagger to make use of that attribute.
It also provides another attribute, [SwaggerResponseExample...
that allows you to define the result-example provider, which can provide a custom good example with data, just like IExampleProvider described above for Core. Neat!
For ASP.NET WebApi2 you can use the attributes SwaggerResponse. This you can Specify the status code and the returning type.
[SwaggerResponse(System.Net.HttpStatusCode.OK, Type = typeof(List<Door>))] [SwaggerResponse(System.Net.HttpStatusCode.NotFound, Type = typeof(string))]
You can find more info here: https://mattfrear.com/2015/04/21/generating-swagger-example-responses-with-swashbuckle/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With