Posts Under Tag: WebAPI

Strategies for Versioning Your RESTful API

The annual Raleigh Code Camp was a great time and the most attended one yet.  This year I presented “Strategies for Versioning Your RESTful API” to a larger room of attendees than I was expecting.  It’s sort of a niche topic, but more API developers are discovering they need a plan for versioning their RESTful APIs as they evolve.  Thanks for all that attended; there was good conversation showing that REST is indeed a topic open to interpretation.

My slide deck can be seen here:

The versioning samples I ran were run in ASP.NET Web API 2 and can be found on GitHub.

Tags: , Filled Under: Programming Posted on: November 10, 2014

FluentValidation With WebAPI 2

The GitHub project description for FluentValidation is succinct and explains what it does better than I could paraphrase:

A small validation library for .NET that uses a fluent interface and lambda expressions for building validation rules for your business objects. 

This is a great open-source library that I’ve been using for years.  One of the things that makes this a great library is its constantly evolving.  Support for the ever-increasing versions of ASP.NET MVC have been kept up to date.  Until recently there was no official support for ASP.NET WebAPI, but that too has changed.

WebAPI 2 support has been released, however the official documentation on CodePlex hasn’t yet been updated to reflect that.  Luckily the documentation for FluentValidation’s ASP.NET MVC integration is there because it’s a good starting point.  However, instead of working with an MVC controller, let’s work with an ApiController.

First, here is a User object and our User validator class:

[Validator(typeof(UserValidator))]
public class User
{
	public int Id { get; set; }
	public string Email { get; set; }
	public string FirstName { get; set; }
	public string LastName { get; set; }
}

public class UserValidator : AbstractValidator<User>
{
	public UserValidator()
	{
		RuleFor(x => x.Id).NotNull();
		RuleFor(x => x.Email).EmailAddress();
	}
}

The validation rules defined above state that a User object can’t have a null Id and the EmailAddress must be a valid email.  Next, create an API controller.  Here is a POST method that will validate the ModelState.  If validation fails, an HttpResponseException will be thrown.  If validation is successful, you would do whatever processing you need (insert/update/etc) and then return a response.

public class UserController : ApiController
{
	public HttpResponseMessage Post(User user)
	{
		if (!ModelState.IsValid)
		{
			// validation failed; throw HttpResponseException
			throw new HttpResponseException(
				new HttpResponseMessage
					{
						StatusCode = HttpStatusCode.BadRequest,
						ReasonPhrase = "Validation failed."
					});
		}

		// validation passed; process record and return success
		return this.Request.CreateResponse(HttpStatusCode.OK);
	}
}

Now that the validator is defined and there’s an API controller, how does WebAPI know to process the validation for the API method’s ModelState?  In the Global.asax’s Application_Start event, the FluentValidationModelValidateProvider needs to be configured (line 10):

protected void Application_Start()
{
	AreaRegistration.RegisterAllAreas();
	GlobalConfiguration.Configure(WebApiConfig.Register);
	FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
	RouteConfig.RegisterRoutes(RouteTable.Routes);
	BundleConfig.RegisterBundles(BundleTable.Bundles);

	// configure FluentValidation model validator provider
	FluentValidationModelValidatorProvider.Configure(GlobalConfiguration.Configuration);
}

If the FluentValidationModelValidateProvider isn’t configured, all ModelState validation checks would return an IsValid value of true, even if validation rules were not met.

Let’s see this in action.  Here is a request that contains an invalid formatted email address:

Invalid HTTP request.

HTTP request with an invalid email address that doesn’t pass validation.

The response is an HTTP 400 indicating that validation failed.  Trying again with a correctly formatted email address returns a successful HTTP status code:

Valid HTTP request

HTTP request with a valid User model passes validation.

Here, validation of the User object was successful and an HTTP 200 was returned from the API controller indicating success.

Tags: Filled Under: Programming Posted on: July 15, 2014

Getting HttpResponseException Details for Your WebAPI Unit Tests

For .NET unit testing assertions, I use Fluent Assertions.  Not only does it result in easier to read assertions, but it makes it easy to dig down in to the details of an exception.  This is particularly important for something like an HttpResponseException that can contain a complex object such as an HttpResponseMessage.  The HttpResponseMessage will have properties that you may want to test such as StatusCode and ReasonPhrase.

FluentAssertions documentation doesn’t (that I know of) show how to get  an object within an exception.  So this post is a reminder to myself of how to do just that.

Here is a simple ASP.NET WebAPI HTTP POST method that performs division.  It’s doing a check to safeguard against a caller attempting to divide by zero.  In the case the caller does attempt to divide by zero, an HttpResponseException is thrown.  The HttpResponseException contains an HttpResponseMessage with a 400 status code along with a reason.

[HttpPost]
public decimal DivideNumber(decimal dividand, decimal divisor)
{
    if (divisor == 0)
    {
        // can't divide by zero
        throw new HttpResponseException(new HttpResponseMessage { StatusCode = HttpStatusCode.BadRequest, ReasonPhrase = "The divisor cannot be zero." });
    }

    return dividand / divisor;
}

To test this, I’d like to verify that the HttpResponseException is thrown and it contains an HttpResponseMessage with an HttpStatusCode of 400 (Bad Request) and the contained reason phrase.  The variable named result is the HttpResponseException.  The result then contains a Response which is the HttpResponseMessage.  The Response then makes it possible to test the properties of the HttpResponseMessage as shown below:

[TestMethod]
public void DivideNumber_WithZeroDivisor_ShouldReturnHttp400()
{
    // Arrange
    const decimal dividand = 10.0m;
    const decimal divisor = 0.0m;
    var controller = new SampleController();

    // Act
    Action ax = () => controller.DivideNumber(dividand, divisor);

    // Assert
    var result = ax.ShouldThrow<HttpResponseException>();
    result.And.Response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
    result.And.Response.ReasonPhrase.Should().Be("The divisor cannot be zero.");
}

Don’t forget to reference FluentAssertions in your unit test project.  It’s available on NuGet.

Tags: Filled Under: Programming Posted on: April 25, 2014