Nancy gets Route Constraints

A couple of people have been after this for a while so I thought I would implement it. This update will give Nancy the ability to have routes that are only called if the parameter of the route fits certain criteria.

The format for the constraints has been copied from the recent WebAPI release. Its really easy to use. All you have to do is define the parameter name and the constraint as part of the route. For example:

Get["/{name:string}"] = parameters => return parameters.Name + " is a string";

This isn't in the prod version of Nancy yet but you can get hold of it in the NancyFX bleeding edge builds nuget package

The constraints available to you are:

Constraint Description
{value:int} Must be an integer value (long is used so any size int can be used_
{value:decimal} Must be have decimal place
{value:guid} Must be a GUID
{value:bool} Must be either true or false
{value:alpha} Must contain only alpha characters
{value:datetime} Must be date time formatted string
{value:min(n)} Must be a numeric greater than n
{value:max(n)} Must be numeric less than n
{value:range(n,m)} Must be a numeric between n and m
{value:minlength(n)} Must be string of length greater than n
{value:maxlength(n)} Must be string of length less than n
{value:length(n,m)} Must be string of length between n and m

If you've looked at the WebAPI implementation of this you may have noticed there are some other options such as long and float that are not included here. I don't think these are really necessary as distinguishing between them isn't really useful for route paramters. better to just have int and decimal. However I will point out that {value:int} does use long so that any size of integer can be used.

As an example to where this is useful. Imagine you want the same route to find a product, but you want to allow a user to use a product id or a product name. The following example will allow you to do that:

public class ProductModule : NancyModule {
    public ProductModule(IProductRepository productRepository)
        Get["/product/{name:alpha}"] = parameter => productRepository.GetProductByName(parameter.Name);

        Get["/product/{id:int}"] = parameter => productRepository.GetProductById(parameter.Id);

I'll let you know when this comes out of beta.