API 2.0 – a more restful proxy around our Api

As we’ve delved further and further into REST and frameworks such as OpenRasta and ServiceStack, I’ve come across a few things that have been niggling me about our own Api. For this innovation time, I wanted to come up with a way of enabling us to kick start our new version of the Api, moving it over to a new framework.

Closer to REST

The few things I wanted to achieve with this first pass were the following, which I’ll go into in a bit more detail shortly:

  • Remove the annoying <response status=””> element from around the entity as this should be handled by Http
  • Return the correct status codes all the way to the client
  • Return the response resource in the correct format as requested in the accept header xml/json or any shiny new format
  • Return OAuth / Authentication responses [http://tools.ietf.org/html/rfc2617#section-1.2 correctly]
  • Have it deploy independently from our existing Api

Also, to make this a worthwhile job, I needed:

  • To be able to get something up and running asap
  • To not have to write very much code
  • For any of the logic to be as clean, simple and as modular as possible

To achieve this I decided to build an Api “proxy” in OpenRasta, utilising the IPiplineContributor system to chain a set of tasks together to intercept and modify the response from a request sent to the 7digital api.

PipelineContributors

PipelineContributors are an OpenRasta concept that allow a developer to hook into the request response process at any point in OpenRastas KnownStages, and modify the current state of this requests ICommunicationContext. As I am running under IIS, the ICommunicationContext implementation is OpenRasta’s version of the AspNet HttpContext.

The interesting thing to me was that you can chain these classes together, e.g:

public void Initialize(IPipeline pipelineRunner)
 {
       pipelineRunner.Notify(GetApiUrl).Before<ApiRouter>();
 }

So this is the route I went down. Currently the PipelineContributors do the following:

FindApiEndpointUri:

As we need to take the current request and route it through to the existing Api v1.2, we first need to find out what the actual API endpoint Uri template is. This is done here using the Linq Except() method to compare the two sets of Uri Segments and return the matching ones, without the host, virtual directory and querystring. This class does exactly this and passes the result up into the pipeline to be used elsewhere.

ApiRouter:

This is where we send a request to the old Api v1.2 using the same endpoint uri and querystring as was passed into the pipeline. It also passes the Api response status code into the pipeline (usually a 200 even on error, but it does return 401s).
It also passes the response into the pipeline.

StripLegacyResponse:

The <response> element is not needed as it contains data that should be handled within the Http header and causes us to have to write extra logic for deserialising our resources within OpenRasta.This PipelineContributor simply strips it out before passing it back along the pipeline.

ApiResponseDeserializer:

This is the final stage and is hooked up to be fired before IHandlerSelection. This is where we deserialise the Api responses into C# DTOs using the SD.Api.Schema library. It then uses a list of Strategy Pattern style rules to see which OperationResult it should be returning, and then sets the context.OperationResult to that.

Each PipelineContributor method returns PipelineContinuation.Continue which tells OpenRasta to continue through the pipeline with our modified Context, so that we can still tap in to the OpenRastas Resource – Handler – Codec concept to output our responses.

Single Handler concept

The idea was that everything essentially hits the API proxy at the root, so we only need one ResourceDefinition, and therefore only need one Handler. This is a very simple class that provides a method for each HttpVerb (Get, Post etc). It then takes the current per request ICommuncationContext (injected by OpenRasta) as a ctor collaborator, and for each method returns the current OperationResult.

Running at website root

I had some problems initially trying to enable OpenRasta to register a Resource at the root Uri (“/”), but after a pit of poking around, I noticed for a number of our projects, we had OpenRastaHttpHandler set to “*.rastahook”.

I realised this needed to be “*”, once I’d changed this (and turned off default web pages) I was able to access at root. Good news if we ever want to create a root endpoint list of uri templates for discover-ability.

Summary

The great thing about this project is that it allows us to have a play around with how we’d like the Api to look whilst the Api v1.2 is still running. It has very little code to maintain and took relatively little effort, but as a result we are now able to support json responses, correct http status codes, and the responses returned adhere much more closely with the Representational State Transfer model.

As I’m using PipelineContributors to modify the request, as and when we need to we can remove/tweak this functionality quite easily. We are also free to move functionality across to this new api without affecting the existing api.

About Greg Sochanik

a .net software developer at 7digital, on the silicon roundabout. Living in angel with his lovely wife, little baby boy and mischievous cocker spaniel. Follow me on twitter @gregsochanik
This entry was posted in OpenRasta, REST, Software Development. Bookmark the permalink.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>