Message Handlers vs Operation Handlers which one to use?

In WCF Web API we have 2 extensibility points which seem very similar. They both are designed for very different reasons. Recently the question of which to use when popped up on our forums. Below is some guidance.

Message Handlers

Message handlers (Currently DelegatingChannel but will be renamed to DelegatingHandler) only deal with http messages (hence the name), you can use them to modify the request or the response or to stop the request and immediately return a response. So in general you use message handlers for addressing http specific concerns, for example:

  • Logging each request (logging the uri)
  • Checking for if-match / if-non-match headers and returning a 304 (not modified)
  • Embedding an ETag header in the response
  • Setting accept headers based on the uri (I do this in the ContactManager)
  • Checking for API keys as in Pablo’s (@cibrax) Handler here, or handling other security concerns like OAuth. (Our OAuth integration in the future will sit here.)

A few things to note about message handlers

  • They are configured per host not per operation
  • They sit very low in the WCF stack in the channel layer making them ideal for security level concerns.
  • They are arranged in a russian doll model meaning each handler calls to it’s inner handler. This lets you do plug in pre-post handling before the handler is called.
  • They only support async (Task<T>)

Operation Handlers

Opeation handlers (HttpOperationHandler) deal with taking the message and manufacturing the parameters for an operation or vice versa. It is the responsibility of the operation handler pipeline to ensure that for every parameter in the method there is a corresponding value it is also the responsibility of the pipeline to take any return/out values and modify the message appopriately with the correct representation. Those values can either be pulled from the message itself (such as parsing the uri into an object) or from custom logic like talking to a respository. The exception here is the value that represents the content of the message. It is the responsibility of the Formatters to handle taking the body and turning into an object or vice versa. Common use cases:

  • Taking a portion of the URI and manufacturing an object. An example of this would be taking a uri like http://maps.com/location/100,00 and turning it into a Location object with latitude / longitude properties.
  • Taking the content and compressing / decompressing it with gzip. Darrel Miller (@darrel_miller) has a nice example of this
  • Logging specific parameters of an operation
  • Validating the body, i.e. someone posts a customer in one of multiple formats. The formatter runs and turns it into a customer (based on conneg) and then the handler validates the model to see that the value are correct.

Here’s the things to note about operation handlers.

  • They are configured per operaiton not per host
  • Manufacture values which are used by other handlers in the pipeline or by the operation
  • They are arranged in a pipeline where each handler is called in succession but one handler does not call the other.
  • They only support sync in the box
  • They can stop the pipeline by throwing an HttpResponseException<T>

Which to use really depends on your scenarios. If you are trying to address pure http concerns use message handlers, if you are trying to address application level concerns that work with models etc, use operation handlers.

This entry was posted in HTTP, webapi. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://twitter.com/NoelAbrahams Noel Abrahams

    I’d like to point out that it makes sense to integrate the WCF and ASP.net worlds a lot more than simply having HTTP bindings for WCF. I’ve just started wiring up a REST-type web service in WCF and find that I need to have completely separate code components for this – i.e. separate from ASP.net filters, model binders, security attributes etc.

  • Anonymous

    I offer to your attention a film about six priorities of the generalized instruments of management by countries and people of Earth.
    Six Principles of Global Manipulation
    http://www.youtube.com/watch?v=0fF3TQ0lJnU
    Anti-Qur’an Strategy of the Bible Project Wheeler-Dealers
    http://http://www.youtube.com/watch?v=_1wXgXwj3MI

  • Anonymous

    You didn’t read it and came to the conclusion that it is mess but you would like your feedback to be taken seriously? 
    Here is the two line summary: - If you want Rack/WSGI capabilities use MessageHandlers.   - If you want strongly typed, easy to test request handling procedures and apply cross cutting concerns across a subset of your resources, use OperationHandlers.

  • http://blogs.msdn.com/gblock Glenn Block

    And what exactly do you think is a mess?

    We’ve had plenty of folks both advisors and community that have said they like both extensibility points and see the value of each. They perform different functions and operate at different scopes. Much in the same way that you have HttpHandler and HttpModule in asp.net. Would you get rid of one?

  • Marcel

     TL;DR: fix this mess, please. Seriously, do you know anyone, besides the guys who wrote this, who said they like the way it is now?