Web API documention using Swagger / Swashbuckle

I have recently been tasked in work with documenting an existing Web API.  This Web API used an older version of Swagger, which had been customised to get around the features that the version did not address at the time. My task was to update that version of Swagger to use the most recent version of Swashbuckle from nuget.  SwashBuckle is used to add Swagger to Web API projects.

The first step was to add Swagger via nuget.

Install-Package Swashbuckle.Core

The next step is to customise the Swagger configuration.  If you use OWIN like our API did, then the Swagger configuration would go into the Startup.cs class.  A basic configuration would look like this;

httpConfiguration
    .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API"))
    .EnableSwaggerUi();

So with the basic configuration out of way, how do you describe what your API actions do?

Go to the project properties – Build – Output.  There will be a checkbox for enabling the XML comments and then a path to an XML file will need to specified, something like “Project.xml”.

Then each API controller action would be decorated with the XML comments that should be familiar but if not:

/// <summary>This is a example</summary>

/// <param name=”example”>Description of example parameter</param>

/// <return>Example return description value</return>

So now to navigate to the Swagger URL.  It should no build the documentation based on the XML comments

https://<your-url>/swagger

The url doesn’t have to be the default.  This can be customised in the Swagger config and changed in “EnableSwaggerUi”

httpConfiguration
    .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API"))
    .EnableSwaggerUi(“docs/ui/app/{*assetPath});

The assetPath parameter will add “index”.  The “index” page can also be customised but it is recommended that you use the template provided by the Swashbuckle site and then you can change the bits that you need to update.  Using a custom page can be achieved by altering Swagger UI section in the config and setting CustomAsset to point to your own “index” file where ever that is in your solution.

The configuration of Swagger is quite extensive and there isn’t a lot you can’t do. 

Issues

I was documenting an existing API and found out that it doesn’t really deal with inheritance (an action was on a base controller).  On doing a bit digging, I seen a few things that stated this was by design.

The other problem I had was with the response XML tags

/// <response code=”200”>Valid example request</response>

Adding the XML tags didn’t work for me, these comments were not added to the Swagger documentation.  I had to rely on Swagger Response data anotations to correctly document the response codes and what they meant in context of our application.

Use the “<remarks>” tag for the implementation notes.

Conclusion

In conclusion, I found Swagger easy to work and easy to configure.  There is plenty configuration options that I didn’t use and might suit your project.  The documentation is good and can only get better.  Swagger gives you a decent alternative to Word documents and keep it all together in one place.

As ever if anything is incorrect or inaccurate, please let me know.

Learning AngularJS–Part 4

Sorry, it has been a while since my last post. 

To finish off the first series of my AngularJS posts, I would like to talk about how I went about updating an existing person and a few other things that I have not covered up to now.

For those who have not read the previous posts you can reach them here The Beginning ,Part 2, and Part 3

Like adding a new person to our personnel record, the application will use the routing engine to determine where to go (“#” represents the routing engine) so our route this time is #/updatePerson.  The route can then work out what controller and partial to use for updating.

Our route provider should look like this:

$routeProvider.when("/updatePerson/:id", {        

controller: "singlePeopleController",        

templateUrl: "/templates/updatePerson.html",   

});

The “:id” part of the url allows the id of the person to be set.  I’ve kept this in the one file but it might be better to split these up into multiple files, my intention is to do that.

The singlePeopleController then retrieves the person using the data service which I created to avoid writing the same code over and over again.  So the first action is to retrieve the person using the id that you have passed in.  I originally retrieved the person by accessing an person object stored in memory instead of using the api to go back to the database but I found that the update was going wrong.  The details were not getting updated, the application would overwrite the new details with the old details.  It was like the save was not happening at all.

After returning the right person, I proceeded with the update.  The person was added to a $scope.Person.  I passed the $scope.person to the updatePerson data service method.  This posted the data to the api and in turn saved it to the database.  If it was successful, it would return it the beginning using $window.location = “/#”. 

var _updatePerson = function (existingPerson) {         var deferred = $q.defer();         $http.put("/api/People", existingPerson)             .then(function (result) {                 var updatedPerson = result.data;                 _people.splice(0, 0, updatedPerson);                 deferred.resolve(updatedPerson);             },             function () {                 deferred.reject();             });         return deferred.promise;     };
function singlePeopleController($scope, dataService, $window, $routeParams, $log) {     $scope.person = null;     $scope.$log = $log;     //$log.log("Id : " + $routeParams.id);     dataService.getPerson($routeParams.id)         .then(function (person) {             // Success             $scope.person = person;             $log.log("Person : " + person.Salutation);         },         function () {             alert("Cannot find person");             //$log.log("Cannot find person");             $window.location = "/#";         });     $scope.update = function () {         dataService.updatePerson($scope.person)             .then(function () {                 $window.location = "/#";             },             function () {                 alert("Cannot update person");             });     };
}

Instead of save() this time I use update().  Update is $scope.update a function which the form uses when the submit is called. i.e. clicking the update button.

One of the issues that I did have to solve was how to put the updated salary into the salary list for that person.  I wanted to search for that person and show the historical salaries for the personnel. 

person.Salary[0].Salary

I’m still not 100% sure if that is correct way of doing this but it works for now.  I went to the forums asking in the Angular JS forum, a couple of people had replied saying that this was a good way to access the list and update it.  I still need to do a bit work on bringing the updated value.

What I still have left to do is implement a search which allows user to search for a person and it would details of their salaries and I would like to add some testing around AngularJS with the ones that I played with is Jasmine / Karma.  That’s because they are on the AngularJS site.

The only other function that I have in the data service is FindPerson, it loops around the people object stored in memory and return the found one if the id of the person matches. 

function _findPerson(id) {         var found = null;         $.each(_people, function (i, item) {             if (item.Id == id) {                 found = item;                 return false;             }         });         return found;     }

Another thing completely off topic and I can’t get right is how to properly format code in blog post.  The formatting seems to go totally awry.  Anyone who knows can contact me please.

I promise I won’t leave it so long next time…my plan is to regularly update this blog so that my technical writing, communication and blog posts improve.

Web Api – Integration Testing

Sorry, it has been a few months since my last post, time flies by and before you know it, the seasons have changed and you haven’t written a blog post in roughly three months.

Anyway, something that I have been working a lot on lately is creating web api applications for a project that I am involved in for work.  The main purpose of this post will be to try and describe the testing method involved.  This is to try to help with two points. One, when I started I didn’t know a lot about web api and the ways that you could test your newly created api.  This could maybe help someone.  Second, to allow me to have somewhere to dump my brain so when I’m asked again I don’t need to search for the information or spend time on the old problems.

To start with, three blogs that I used were:
In memory client, host and integration testing of your Web API service
ASP.NET Web API integration testing with in-memory hosting
Integration testing ASP .NET Web API

Glenn Block has written a book covering web api
Designing Evolvable Web APIs with ASP.NET

I was also very lucky that someone inside the company I work for had arranged for Glenn Block to talk to the developers and the same person had almost completed the template that we would use to write the api but they had followed a different approach for testing, particularly integration testing.  Going for a self hosted solution and this involved using the full IIS to deploy the application and run tests against that application.  In the project I am involved in, we used IIS Express and changing the web server wasn’t an option plus I had to write tests that could run and safely clean up after themselves in the continuous integration (CI) server. I opted for the in-memory integration tests.

I started off creating an infrastructure library for my configuration classes, interfaces and server class.  The configuration class consisted of all the plumbing for Castle Windsor and routes and filters for my api project and the server classes utilised the configuration classes to set the http configuration and http server to use in my tests. Then called the classes in the infrastructure library from the main api project.  I also had both unit and integration test projects.  I have seen some create an project to house all the models and any other logic necessary.  Essentially use the main api project as a host only but I did not want to create a large number of projects so opted to use my main project to hold the models and some configuration code.

Structure:
– Api – controller and view models.
– Infrastructure – in-memory server and configuration.
– Integration tests – for the api code only.
– Unit tests – for the api code only.

The command and queries that were executed from the api project were all housed in another project and had their own test projects.

One of the main issues that I had was how to dispose of the Castle Windsor container after each test run.  The test harness would only run one test successfully.  It would fail the other tests but if you ran the other tests individually they would pass.  It was not disposing of the classes the way it should or we were not setting the lifecycle up on the classes right.  If we set up the configuration in the constructor of the server class it would fail as well with the same error that it could not dispose of the object.  In the end, a new container was created on each test and this solved the issue.  There was no way to remove the items from an existing container.  I would be interested in hearing from anyone that has solved that problem in a different or better way.

One of the other issues was the serialized auto properties were generating the k_backingfield text and as a result automapper could not resolve the property names.  The data returned was always null.  A couple of ways to resolve this were using [Data Contract] at the top of the class with [Data Member] for each of the properties or using the Newtonsoft.Json Library using the data annotation [JsonProperty] with the k_backingfield added to the name above the property.

One of the things that I did in case we ever wanted to go down the self hosted route was to create an in-memory test class, which inherited the actual test class.  This way it was simple enough to create a self hosted test class, which inherited the actual test class without repeating code or configuration over and over.

Example:
[TestFixture]
public class InMemoryApiTests : ApiTests
{
public InMemorysApiTests() : base(new InMemoryApiServer())
{
}
}

One tool that proved invaluable was the Postman REST client, it is a chrome plugin and I used this to compare the outputs that I got from the tests and the returned data in post value to make sure everything was good.

I have now implemented another api and this time it was a lot easier because I could use the pattern developed earlier to test.  Testing was by the far the greatest challenge that I faced when developing the api.

Until next time…..As ever any feedback on the way I write these posts or the content is appreciated.