MVC API Routes by Type in C#

In MVC 3 onwards you can constrain routes based on your own rules.

MVC’s default API route is /api/{action}/{id} and uses the controller and action based on the controller name and HTTP Verb.

I wanted a way to route anything with /api/version/<controller> to a specific collection of controllers, based on a naming convention of my choice. I decided to use a constraint based on interfaces, but you could implement the match using Regex or any number ways. As long as you implement a IRouteConstraint you can decide your own route logic.

Lets create an empty interface which we’ll use a flag. We only want the route to apply for an API controller that implements this interface.

public interface IVersionApi
{ }

Here’s an example of one of our API controllers which implements our IVersionAPI. Note this class implements the IVersionAPI interface.
This will be hit when I called /api/versions/FlightTracker and it will still support default HTTP verbs (so Get() will be hit for a HTTP GET request).

public class FlightTrackerController : ApiController, IVersionApi
{
  private readonly IFlightTrackerVersionRepository _flightTrackerVersionRepository;
  private readonly IConfiguration _configuration;
  public FlightTrackerController()
  {
    _configuration = new Configuration();
    _flightTrackerVersionRepository = new FlightTrackerVersionSqlRepository(_configuration);
  }
  public IEnumerable Get()
  {
    var result = _flightTrackerVersionRepository.Get();
    return result;
  }
}

Here’s the additional WebAPI route which sets up our route. Note the new constraint object where everything gets tied together.

config.Routes.MapHttpRoute(
  name: "Versions",
  routeTemplate: "api/versions/{controller}/{id}/{format}",
  defaults: new { id = RouteParameter.Optional, format = RouteParameter.Optional },
  constraints: new { abc = new TypeConstraint(typeof(IVersionApi)) }
);

The magic happens our TypeConstraint class. It gets a list of all the types which implement IVersionApi, then compares the requested controller (e.g., a request for “/api/versions/FlightTracker” will match “FlightTrackerController”) with each of the types then returns a bool. We implement the MVC IRouteConstraint interface – see Creating a Custom Route Constraint.

public class TypeConstraint : IRouteConstraint
{
  private readonly Type _type;

  public TypeConstraint(Type type)
  {
    _type = type;
  }

  public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
  {
    var controller = values["controller"];

    if (controller == null || string.IsNullOrWhiteSpace(controller as string))
  	  return false;

    var type = _type;
    var types = AppDomain.CurrentDomain.GetAssemblies()
	  .SelectMany(s => s.GetTypes())
	  .Where(type.IsAssignableFrom);

    var matchWith = controller + "Controller";

    if (types.Any(o => o.Name == matchWith))
	  return true;

    return false;
  }
}

Hope you find it useful!

Flow – Workflow template based software

Flow is my experiment into workflow template based software.

Rigid software is a pain to customise

I used to work in a company where their source of revenue was from sales of a single software package. This software package was designed to record customer information and then schedule and manage jobs to service the customers equipment. The package was generic in order to fit as many domains as possible. This confused lots of customers because the items they sold weren’t in the language of the customer. For example, instead of selling or maintaining houses and equipment, they’d have to use products and parts, so would refer to houses as products and equipment as parts.

Every day there would be requests for additional functionality, or a change of its behaviour because it didn’t mirror the way they work closely enough. For example, customers sometimes needed to send an email or calculate a field elsewhere after something had been added to the system. If we added an additional step for one customer, it would affect another customer who wanted the opposite Where do you stop when you start to alter the software for one customer but need it to be generic? That is still a problem for my old company.

Like clothes, we need something simple as a general fit to get started, but then as we mature we can get something tailored which would suit us better and be less wasteful.

How would this work? Lets take this example of adding a new customer. We collect the data from a form and store it in the database.

Flow 1

If this was traditional software, after it’s been shipped, the process can’t be altered because the routines are hard coded. What happens if your biggest customer comes to you now asking you to alter this process because it’s important for them to send an email to the Customer Team every time a new customer is added to the system? Looks like you’ve got to go back and recode the software, then ship it with a set of feature toggles so it sends emails:

Flow 2

Imagine if the software we shipped was a system of workflow templates. If a customer wanted an additional custom action, they could add additional steps wherever they needed to. Customers that just wanted off-the-shelf-software wouldn’t need to do a thing, as they’d never make any changes.

Templated actions or their properties could be locked at the discretion of the template developer leaving everything else would open to customisation. Locking actions is only useful when updating the software versions, so an upgrade would update all the standard actions – the ones that were supported, and wouldn’t remove any custom actions. If actions were removed by the developer, this would cause a few merge issues so that needs thinking about.

Flow

I think I’d quite like to create a workflow template based solution. I’m going to concentrate on something web based to start with, designed to be portable for any platform. I’m going to write it in C#, and probably hosted in Azure to start with. It’s also going to be designed so it can be taken offline and needs a way that it can be updated, tested, and rolled back.

Actions

  • Collecting data
    This would need forms, form templates, and tie in with validation
  • Validating data
    This would be a custom rules engine linked to any step
  • Storing data
    Where do you store data? How do you set this up? NoSQL would be perfect for this. If we were going to store to a relation database, then mappings would have to be maintained.
  • Sending emails (to customer, internally)
    These need lists of emails, HTML templates, etc.
  • Push notifications
    Send info to phones and push enabled devices in real time. That would be neat.
  • Showing information to the user
    If the user is doing something important, or needs to accept a message first, we’d need a way to show it to them.

Right, enough for tonight, back to work in the morning.

Understanding the 2013 Microsoft Azure Offerings

The Intro to Windows Azure page on the Azure site gives a very good and clear overview of the different compute, data, networking, analytics, messaging, caching and identity solutions on offer.

  • Compute/Execution Models
  • Data storage
  • Networking
  • Business Analytics
  • Underlying apps (Messaging, Caching, Identity)
  • APIs (Marketplace, Store, Media, etc.)

Compute

Virtual Machines – These are entire virtual machines backed with APIs and golden images. VHDs can be used and transferred from onsite to cloud as needed. Anything you can think of using a server for can be done with Virtual Machines and they’re completely customisable. You have the overhead of maintaining them though.

Web Sites – These are managed sites, much like you’d get from a website provider like GoDaddy or Fasthosts. They’re managed by Azure and can be shared instances (so on the same box as other companies websites), or standard (one website per box). The standard versions can be scaled. These are managed by Azure infrastructure and provide APIs and support for Node.js, PHP and Python. Traffic is distributed and managed by Azure Web Sites. Once a site is running, they can be scaled out automatically or manually. They also support MySQL and WordPress, Joomla and Drupal. These are ideal for small websites created in Visual Studio and uploaded automatically or via API. Websites don’t give you admin access to the box so you can’t remote in – Cloud Services do give you these options.

Cloud Services – These are one of the most flexible solutions. These are web apps (web facing, hosted by IIS) and/or compute roles hosted in a managed execution environment (think automatically started console app). These roles are managed by Azure and can be scaled automatically or manually. These roles are restarted approx once per day and are automatically updated to the latest version of the operating system as they become available. You can remote to these boxes as an administrator.

Mobile Services – These are several APIs and tools which accelerate mobile development including native client libraries for Windows, iOS, Android and HTML. There are REST APIs for push notifications (SendGrid and Pusher) for each platform and tools to provision storage and databases. These tools have been created as components so you do not have to worry creating any underlying infrastructure yourself.

Data

In all cases, when data is stored, it is replicated across three different computers in the Azure datacentre to provide high availability. You can access the data using RESTful backed client libraries and so can be accessed from anywhere that has internet access (so from the instances, or a phone, or computer via the internet). These can be secured with passwords or certificates, or put behind your own protected endpoint.

SQL Databases – These are MS SQL databases but have a slightly reduced set of commands that can be used with them. They are scalable and are very powerful and fast. See SQL Server Feature Limitations (Windows Azure SQL Database) for more information on the reduced feature set. There are always workarounds for the slight limitations, so don’t be put off.

Tables – These are key value NoSQL tables and are stored in Microsoft Azure Table Storage providers which is a RESTful API backed with native client libraries. They’re very easy to use to find and store data. These can be searched very quickly.

Blobs – This is key/value storage for unstructured binary data (files). These are slower to search but can store anything.

Networking

Virtual Networking – You can extend your current network on demand to your own part of Azure, and you can bring up or tear down instances and storage as needed. Useful for small networks or providing intranet apps.

Traffic manager – Like AKAMAI and other routing providers, when you have global applications you may wish to shape traffic differently for each country or user profile. If your applications are stored in different datacentres around the world, Traffic manager allows you to direct client requests to certain datacentres.

Analytics

SQL Database Reporting – This is SQL Reporting Services (SSRS) on a hosted Windows Azure Virtual machine. When used in combination with Microsoft Office, you have a powerful way to create reports and charts and directly import them into Excel.

HD Insight – This is Microsofts implementation of Hadoop (MapReduce). HD Insight spreads the job across a configurable level of nodes and uses the Hadoop Distributed File System (HDFS) to share data. HD Insight clusters can be created and destroyed on demand so you will only be charged when you need them.

Messaging

Queues – You can think of Azure Queues as high availability distributed ordered lists, like a distributed MSMQ. There are RESTful backed client APIs for them. You can also query and add items on the fly. Queues can be created and destroyed programatically. They are extremely quick and are great for sending information from a source which does not need acknowledgement or where the volume will change over time. These are effectively store and forward queues, so you can get one or more Worker Roles to later grab the data and work with it.

Service Bus – These are similar to Queues but also provide a publish-and-subscribe model (queues just push and pop). The Service Bus has the notion of Topics which can be subscribed to by clients. Service Bus therefore allows one-to-many communcation and allows direct one-to-one communcation via its Relay Service, where messages can get through firewalls because both endpoints are connected to secure cloud endpoints. EasyJet use this to connect its halo systems from secure backends to terminals in the airport.

Caching

Application Caching – There are a number of solutions here. This can be either single instance in-memory caching, multiple instance in-memory caching, or single/multiple filesystem backed caching. Caching is key value and can expire. You can opt for a single instance to reserve a percentage of space for caching, or multiple instances to reserve a percentage or spaces, or you can reserve an entire instance for distributed caching. See more at Windows Server AppFabric Caching Features.

CDN – Content Distribution Network allows content to be cached closer to the end user. So if there’s a server that’s physically closer to the user, the content can come from that server, instead of another one on the other side of the world. Think Akamai.

Identity

Windows Azure Active Directory – This is AD in Azure for cloud applications and it comes with a RESTful API. This isn’t full blown AD, but if you need AD, you can use a virtual machine with AD installed on it.

Windows Azure AD Access Control – This provides a third party identity store and can be run standalone with certificates or can be extended to work with third party identity providers such as Facebook, Google and others. Access Control acts as an intermediary for the other providers and consolidates them all into a single access model and API. You can use this approach for single-sign-on for many providers to your app. Standalone identity providers can be excessively complex because they must self sign their own certificates and can be difficult to diagnose.

I hope that gives you an overview of the different offerings. See more info at the Windows Azure fundamentals page.