I'm not going to do full comparison, because I've not used web api in anger yet, and I don't want to be arguing for or against either frameworks, but here is some info on how to do some of the stuff you're going to want to know if considering a move from OpenRasta to ASP.NET MVC4's Web API (or perhaps just starting out in the resful framework space and have chosen Web API).
Pipelines
One thing I love about OpenRasta is the pipeline stuff - very easy.
But I have to say, Web API's making it pretty easy too ...
Note I'm injecting in a service ... its as easy as it should be
public class MyPipelineInterceptor : System.Net.Http.MessageProcessingHandler
{
readonly ISomeService _service;
public MyPipelineInterceptor(ISomeService service)
{
_service = service;
}
protected override HttpRequestMessage ProcessRequest(HttpRequestMessage request, CancellationToken cancellationToken)
{
return request;
}
protected override HttpResponseMessage ProcessResponse(HttpResponseMessage response, CancellationToken cancellationToken)
{
return response;
}
}
Dependancy Resolution
Again pretty darned easy, and I have to say (sorry Seb), easier to inject your favourite DI framework than OpenRasta 2's.
This is using Structuremap :
GlobalConfiguration.Configuration.ServiceResolver.SetResolver(
t =>
{
try
{
return ObjectFactory.GetInstance(t);
}
catch (Exception)
{
return null;
}
},
t =>
{
try
{
return ObjectFactory.GetAllInstances(t).Cast<object>();
}
catch (Exception)
{
return new List<object>();
}
}
);
Pretty easy to configure :
GlobalConfiguration.Configuration.MessageHandlers.Add(new MyPipelineInterceptor(ObjectFactory.GetInstance<ISomeService>()));
Handlers
Handlers are minimal, and feel a lot like OpenRasta's.
Instead of OperationResult you have HttpResponseMessage.
The routing is handled automagically via a single call
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
public class ValuesHandler: ApiController
{
readonly ISomeService _someService;
public ValuesHandler(ISomeService someService)
{
_someService = someService;
}
public HttpResponseMessage Get()
{
return new HttpResponseMessage(new[] {"value1", "value2"}, HttpStatusCode.OK);
}
public HttpResponseMessage Get(int id)
{
return new HttpResponseMessage("value1", HttpStatusCode.OK);
}
public HttpResponseMessage Post(string value)
{
return new HttpResponseMessage(HttpStatusCode.Created);
}
public HttpResponseMessage Put(int id, string value)
{
return new HttpResponseMessage(HttpStatusCode.NoContent);
}
public HttpResponseMessage Delete(int id)
{
return new HttpResponseMessage(HttpStatusCode.NoContent);
}
}
Pipeline injection
So one of the patterns we use (see https://github.com/agilex/agilex.persistence.openrasta) is injecting a repository into OpenRasta's CommunicationContext's PipelineData before any request, and disposing it after every request (kinda AOP style).
Chucking *global* resources into your pipeline is easy in Web API too ... in your interceptor (the first class in this post) :
request.Properties.Add("thing", new MyThing());
And then you can just access the properties in your handler/controller too, or on the response method on your pipeline interceptor.
So overall, pretty impressive so far.
As I said, I've not used it in anger yet, so not sure how it stacks up with trickier usuage (like complex model binding, or one-to-many route relationships - ie /users/123/orders), but to be fair, considering the model binding stuff is from asp.net mvc, and the routing is pretty similar, I'm sure it will be fine.
No comments:
Post a Comment