Swashbuckle Pro Tips for ASP.NET Web API – XML

In the previous post, we implemented IOperationFilter of Swashbuckle to handle example objects with combination of AutoFixture. According to Swagger spec, it doesn’t only handle JSON payloads, but also copes with XML payloads. In this post, we’re going to use the Swashbuckle library again to handle XML payloads properly.

The sample codes used in this post can be found here.

Acknowledgement

The sample application uses the following spec:

Built-In XML Support of Web API

ASP.NET Web API contains the Httpconfiguration instance out-of-the-box and it handles both JSON and XML payloads serialisation/deserialisation. Therefore, without any extra efforts, we can see those Swagger UI pages showing both JSON and XML payload.


As Swashbuckle is a JSON-biased library, camelCasing in JSON payloads is well supported, while XML payloads is not. All XML nodes is PascalCasing, which is inconsistent. How can we support camel-case on both JSON and XML? Here’s the tip:

It’s a little bit strange that, in order for XML to support camel-casing, we should change JSON serialisation settings, by the way. Go back to the Swagger UI screen and we’ll be able to find out all XML nodes except the root one are now camel-cased. The root node will be dealt later on.

Let’s send a REST API request to the endpoint using an XML payload.

However, the model instance is null! The Web API action can’t recognise the XML payload.

This is because the HttpConfiguration instance basically uses the DataContractSerializer instance for payload serialisation/deserialisation, but this doesn’t work as expected. What if we change the serialiser to XmlSerializer from DataContractSerializer? It would work. Add the following a line of code like:

Go back to the screen again and we’ll confirm the same screen as before.

What was the change? Let’s send an XML request again with some value modifications.

Now, the Web API action recognises the XML payload, but something weird happened. We sent lorem ipsum and 123, but they’re not passed. What’s wrong this time? There might be still the casing issue. So, instead of camel-cased payload, use pascal-cased XML payload and see how it’s going.

Here we go! Now the API action method can get the XML payload properly!

In other words, Swagger UI screen showed the proper camel-cased payload, but in fact it wasn’t that payload. What could be the cause? Previously we set the UseXmlSerializer property value to true for nothing. Now, all payload models should have XmlRoot and/or XmlElement decorators. Let’s update the payload models like:

Send the XML request again and we’ll get the payload!


However, it’s still not quite right. Let’s have a look at the actual payload and example payload.

The example payload defines ValueRequestModel as a root node. However, the actual payload uses request as declared in the XmlRoot decorator. Where should I change it? Swagger spec defines the xml object for this case. This can be easily done by implementing the ISchemaFilter interface of Swashbuckle.

Defining xml in Schema Object

Here’s the sample code defining the request root node by implementing the ISchemaFilter interface.

It applies the Visitor Pattern to filter out designated types only.

Once implemented, Swagger configuration needs to include the filter to register both ValueRequestModel and ValueResponseModel so that the request model has request on its root node and the response model has response on its root node. Try the Swagger UI screen again.

Now the XML payload looks great and works great.

So far, we’ve briefly walked through how Swagger document deals with XML payloads, using Swashbuckle.

Swashbuckle Pro Tips for ASP.NET Web API – Example(s) Using AutoFixture

In the previous post, we implemented IOperationFilter of Swashbuckle to emit the consumes and produces properties in a Swagger document. This post will implement another IOperationFilter to emit example(s) properties containing auto-generated values by AutoFixture.

The sample codes used in this post can be found here.

Acknowledgement

The sample application uses the following spec:

Defining example(s) in Operation Object

There are a few places, in a Swagger definition, where example objects are declared:

  • example property in parameter
  • examples property in responses
  • example field in definitions

Swashbuckle library automatically generates those example data with default values based on their data type. In other words, if its data type is string, the example value becomes string, if its data type is number, the example value becomes 0, and so on:

Is there any way that we can have a sort of meaningful data in those example objects? Of course there is. This NuGet package helps us create more meaningful example objects. Download the package and write some codes like:

Then add a decorator to an action of Web API:

The first one, SwaggerResponse, is built-in Swashbuckle decorator and the second one, SwaggerResponseExample is what we’re going to use for example data generation. Once the decorator is added, we need to add another OptionFilter acton in the Swagger config file like:

Reload the Swagger UI page and we can see the example object with more meaningful values:

This is how the Swagger definition looks like:

This is certainly a good way to show example data. But when we refresh the page, the example objects still show the same value as we hard-coded them.

Automatic Example Data Generation with AutoFixture

We were able to generate an example object by implementing IExampleProvider of Swashbuckle.Examples library. What if we want to create an example object with automatically generated values? AutoFixture is for unit testing by generating a fixture instance with random values. Why not using this for our randomly generating examples? Let’s have a look. This time, we create an abstract class to apply both requests and responses.

The abstract class, ModelExample, internally implements IFixture from AutoFixture and creates a random instance of the type T. Here are request and response classes inheriting the abstract class:

And this is the action method of a Web API. SwaggerRequestModel defines the request example and SwaggerResponseExample defines the response example.

Reload the Swagger UI page several times.

Each time the page is refreshed, the example objects have different values. If we need to put some restrictions like string length or value range, we can simply put other decorators like StringLength or Range on those request/response models.


So far, we have walked through how Swashbuckle library could generate example(s) object with meaningful values rather than default values. There are many other cases that we can customise Swashbuckle library to enrich Swagger document. I’ll introduce some other cases later on.

Swashbuckle Pro Tips for ASP.NET Web API – Content Types

Open API 2.0 (AKA Swagger) is a de-facto standard to document Web API. For ASP.NET Web API applications, Swashbuckle helps developers build the Swagger definition a lot easier. As Swashbuckle hasn’t fully implemented the Swagger specification, we need to develop some extensions using a few interfaces provided by Swashbuckle. In this post we’re going to talk about a couple of extensions to make Swagger definition more completed.

The sample codes used in this post can be found here.

Acknowledgement

The sample application uses the following spec:

Defining consumes and produdes in Operation Object

In Swagger, HTTP verb like GET, POST, PUT, PATCH or DELETE is referred as Operation Object. Each Operation Object can define which content types are to be requested (consumes) and which content types are to be returned (produces). Therefore, with Swashbuckle, Swagger document page produces like:

In other words, Swashbuckle assumes those five content types as default for requests – application/json, text/json, application/xml, text/xml, and application/x-www-form-urlencoded. And those four content types are the default response ones – application/json, text/json, application/xml and text/xml. Here’s a part of the Swagger definition automatically generated.

If we want to globally apply those content types, that can be done within the global configuration. Here’s the sample OWIN configuration:

It clears everything and add only one content type – application/json. By doing so, we can globally set one content type for both requests and responses. If we want to have more control on each endpoint, the IOperationFilter interface of Swashbuckle gives us that flexibility.

Implementing SwaggerConsumesAttribute Decorator

First of all, we need to write a simple decorator, called SwaggerConsumesAttribute which handles the consumes field of the Operation Object.

Through this decorator, we simply define number of content types to pass. How does it apply?

Let’s move on.

Implementing Consumes Filter

We now write the Consumes filter class by implementing the IOperationFilter interface like.

What it does are:

  • To check the content type values passed from the SwaggerConsumerAttribute decorator, and
  • To add all content types passed from the decorator to operation.consumes.

This needs to be added to the Swashbuckle configuration like:

Now run the Web API again and we’ll see the result like:

Implementing SwaggerProducesAttribute and Produces

Both SwaggerProducesAttribute decorator and Produces filter can be written as what we did above for consumes.

The SwaggerProducesAttribute decorator can be applied to:

The picture below is the Swagger definition based on the extensions above:

We’ve so far had a look how to extend Swashbuckle to fill the missing parts in Swagger definition. In the next post, we’ll walk through another extension for Swagger definition.

Creating Service Contract with AutoRest, Swagger and HAL

According to Richardson Maturity Model, REST API level 3 should provide hypermedia within responses as metadata, so that users can easily navigate to other resources. This is particularly important if Microservices architecture (MSA) is considered for your service or application. Because MSA is a collection of small REST API services, each API server should provide complete set of documents or manuals for others to consume it properly. In order to provide document automation, Swagger is one of the best choices, and HAL, in order to provide hypermedia within the response, is also yet another option. Of course, consuming those REST API at client applications is also important. In this case, AutoRest can give great benefits for your development. In this post, I’ll discuss HAL, Swagger and AutoRest with some demo code.

Integrating HAL

HAL (Hypertext Application Language) has been suggested by Mike Kelly. Its formal specification can be found at this IETF draft. Generally speaking, many REST API services are well structured. They don’t just only return data in the response, but also include various metadata for reference purpose, in their own way. HAL offers a standardised way of including hyperlinks into those responses. Here’s an example

If you send a request with the URL above, the expecting response will look like:

However, if HAL is applied, the response will look like:

Let’s see another example returning a collection.

The request will expect response like:

If HAL is applied, the response will look like:

Can you see differences? HAL applied responses contain much richer data that can easily navigate to other resources.

OK, theory is done. Let’s implement HAL on your API. First of all, assuming you’ve got an existing Web API app containing models of Product and ProductCollection looking like:

There are many HAL implementations on our NuGet. For now, I’m going to use WebApi.Hal. Once installed, you can modify those models with this way, by minimising impacts on the existing application:

Then, register HAL into your Global.asax.cs or Startup.cs:

That’s it! Too simple? Here’s the magic inside the Representation class. It has the public Links property that takes care of all hypertext links. All we need after the HAL implementation is to add appropriate links to each instance, manually or automatically. Here’s a way to include hyperlinks manually within a controller level:

Once it’s done, build it and check the API response. Then you’ll see the result including those HAL links like above. Now, let’s move to the next part, Swagger.

Integrating Swagger

According to Swagger website, Swagger provides a standard, language-independent interface to REST API so that both humans and computers can easily find and understand the API structure without reading source codes or documents. There are several other alternatives like RAML or API Blueprint, so it’s up to you which one should you choose.

Swashbuckle is one of C# implementations of Swagger. It’s easy to use and virtually zero configuration is required for the basic usage. Let’s install Swashbuckle into your project. Once installed, it also adds another file, SwaggerConfig.cs under the App_Start directory. You can directly use it or do some modification for your application. Let’s have a look.

When you open SwaggerConfig.cs file, it looks like above. In order for you to have more control on it, comment out the first line, [assembly: ...] and make the Register() method to be an extension method:

Then, put the following like into either your Global.asax.cs or Startup.cs for registration:

That’s all. Build and run your app, type URL like http://my.api.service/swagger and you will see the Swagger UI screen like:

What you need to notice is the JSON schema URL in the picture above. When you type the URL from Postman, it will look like:

This is basically a JSON schema file and pretty much equivalent to WSDL from SOAP. With terms of WCF, it contains both service contract and data contract so, with this schema, your client applications can access to the API and consume it. There’s no obstacle for it.

So far, we’ve implemented both HAL and Swagger on your REST API server. How can we then consume those APIs on your clients like web app or mobile app? Let’s move onto the next section for this.

Deserialising Swagger JSON schema with AutoRest

Once Swagger JSON schema is generated, your client apps should be able to consume it with minimised efforts. AutoRest can bring great benefits to your client apps. It automatically generates both service contracts and data contracts pointing to your REST APIs using Swagger JSON schema. Currently, AutoRest supports C#, Java, Node.js and Ruby and the number of languages gets gradually expanded.

Here’s an ASP.NET MVC app. Within the app, assuming there’s a folder, Proxies. Swagger JSON schema file is then placed into that folder with name of swagger.json. Then install AutoRest CLI app and runtime library from NuGet. In order to auto-generate client libraries, try the following command on your Command Prompt:

What does the command line mean? Here’s the brief explanation:

  1. Run AutoRest.exe
  2. Input JSON schema name is swagger.json
  3. The namespace for auto-generated files is HalSwaggerSample.WebApp.Proxies
  4. Store auto-generated files into Proxies
  5. Set output file type as C#

After the generation, you will be able to see bunch of files have been stored into the Proxies folder. The most important file is HalSwaggerSampleHalApiApp.cs. Of course, the file name (or class name) will be different from yours. It provides the service endpoint and service contract information. It also contains the corresponding interface, IHalSwaggerSampleHalApiApp, so this service contract is testable, mockable and injectable. Therefore, your controller/action can be written like:

Therefore, the result screen will look like:

Did you find that can’t be easier?

We’ve so far had a look at HAL, Swagger and AutoRest. Both HAL and Swagger are to design your REST API to be more discoverable, readable and maintainable and make client apps build their access point much easier with tools like AutoRest. How about implementing those into your Web API, if you’re considering MSA? Kloud can help you.

The entire sample source code that I wrote for this post can be found at here.