WCF Web API–Processing Architecture

This is the sixth post on a series about the new Preview 4 of WCF Web API. The previous posts were:

This post aims to present the processing architecture: what happens since a HTTP request message is received by the WCF Web API runtime until the HTTP response bytes are written into the transport layer.

The following description reflects my understanding of the WCF Web API runtime, based on the source code, and may not be completely accurate. Comments and corrections are greatly appreciated.

0. The big picture

The following diagram aims to schematize the HTTP request processing architecture.

Runtime2

In the bottom layer is the interface between the WCF runtime and the transport layer, namely the transport channel and the message encoder/decoder. The resource class, composed by a set of operations that handle HTTP requests and produce HTTP responses (for more details, see the first post), is at the top layer.

1. From bytes to HttpRequestMessage

The journey begins at the bottom layer, where a sequence of bytes obtained from the transport protocol is transformed into a HttpRequestMessage instance by WCF’s transport channel and message encoder/decoder.

2. Message handlers

After creation, the HttpRequestMessage instance passes through a sequence of message handlers. Each one of this message handlers receives an HttpRequestMessage and returns a HttpResponseMessage asynchronously. Being more precise, the message handlers expose the following method

Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)

 

Each message handler has a reference to the next handler in the sequence, called the inner handler. A typical usage scenario is for the handler to perform some processing over the request message (e.g. read an header and add a property to the message, change the request method) and then forward it to the inner handler. After the inner handler returns the response, then another processing can be done over this response message (e.g. add an header) before it is returned.

MessageHandler.Passthrough

Another usage scenario is for the handler to produce the response message immediately and return it without forwarding the request to the inner handler. This means the the upper layers of the runtime will not be called, namely the resource class.

MessageHandler.Stop

For a concrete example of these two scenarios, consider a channel that implements HTTP Basic Authentication:

  • The SendAsync method inspects the request message to see if it contains an Authorization header with valid credentials. If so, it adds a property with the user’s identity to the message and lets the request flow to the inner handler. In this case, the handler’s return will be the inner handler’s return.
  • If the Authorization header does not exists or has invalid credentials, then a 401 response message is created with a WWW-Authenticate header. This response message is returned immediately, that is,  the inner handler is not called – the request processing is short-circuited.

The message handlers provide an asynchronous interface that, given a HttpRequestMessage, returns a Task<HttpResponseMessage>. This means that message handlers are an adequate place to perform lengthy I/O operations without blocking the processing thread. Using the above concrete example, implementing HTTP Basic Authentication, this I/O operation can be the retrieval of the user’s roles from an external service/resource/database.MessageHandler.IO

For a concrete example of a message channel, see http://weblogs.asp.net/cibrax/archive/2011/04/15/http-message-channels-in-wcf-web-apis-preview-4.aspx. Note that currently message handlers are still called message channels.

3. Dispatching

If the request message survives all the message handlers, the next phase in the request processing is the operation dispatch. In this phase, the request’s method and URI are used to select the operation that will be called. This selection uses the operation’s WebGetAttribute or WebInvokeAttribute to obtain the operation’s method and URI template. The request is then forwarded to the selected operation, via the operation handlers.

If no operations matchs the request, then a 404 response is produced.

4. Operation Handlers

The next processing phase is responsible for producing the parameter set required by the selected operation, from the request message. This parameters are produced by operation handlers. These operation handlers may also be used to perform other type of operation specific message processing (e.g. operation caching).

Message handlers receive a request message and produce (asynchronously) a response message. Operation handlers, on the other hand, receive a set of parameters and produce (synchronously) another set of parameters. These parameters are described by the HttpParameter class, namely

  • by a name;
  • and by a type.

There is another difference between message handlers and operation handlers: message handlers apply to every request; operation handler apply only to the operation where they where added. This is illustrated in the first diagram: there is one message handler “stack” and multiple operation handlers “stacks”.

Each operation handler derives from the HttpOperationHandler class and must implement the following methods:

  • OnGetInputParameters – returns an IEnumerable<HttpParameter> with the parameters that the handler wants to receive.
  • OnGetOutputParameters – returns an IEnumerable<HttpParameter> with the parameters that the handler produces.
  • OnHandle – receives an object[] with the input parameter’s values and returns another object[] with the output parameter’s values.

Each operation handler receives parameters from a parameter bag (input parameters) and contribute with parameters to that bag (output parameters).

OperationHandlers

Initially, this bag is populated with the request message itself. Afterwards, the OnHandle method of each handler is executed, resulting in more parameter values added to the bag.

The operation handlers are execution by an order that satisfies the handler’s dependencies: when a given handler executes, all of its input parameters must already be in the bag, produced by previously executed handlers. This execution order is determined during service startup, based on the input and output characterization of each handler (OnGetInputParameters and OnGetOutputParameters).

The execution order must also guarantee that, at the end of this phase, all the operation’s input parameters are  available in the bag.

If this order does not exists, e.g. an operation handler or the operation uses a parameter that isn’t provided by any other handler, then a runtime error occurs.

An example operation handler was showed in the third post.

Another interesting operation handler to analyze is the UriTemplateHandler. This handler, added automatically by the WCF Web API runtime, receives the request messaged and matches the operation’s URI template with the request URI. Then, it outputs one parameter for each bound variable. This is the way how variables are extracted from the URI, both from the path and from the query string, and turned into operation’s parameters.

5. Instance creation

Before the operation is called, a resource class instance is obtained – operations are instance methods.

It is possible to plugin a custom instance provider for obtaining these instances. A typical scenario is the use of an IoC/DI container for that purpose.

6. Operation invoke

Finally, at the topmost layer, the operation is invoked using the parameters computed by the operation handlers.

7. Response operation handlers

After the operation’s invocation, the output parameters pass through a sequence of response operation handlers. One of the most interesting things happening in this phase is the content encoding, which will be the subject of another post.

Also, if the response message was not returned by the operation, it is created in this phase

Finally, the response message flows down through the message handlers until being turned into a byte sequence and written into the transport layer.

Concluding remarks

  • This post does not describe how custom message or operation handlers are added to the runtime. This will be the subject of a future post about configuration.
  • In the following posts I will also present in more detail some of the described phases.
  • Once again: comments, corrections and suggestions are welcomed.
Advertisements

10 thoughts on “WCF Web API–Processing Architecture

  1. machadogj

    Hey, very cool article, could you complete the diagram with the serialization/deserialization stages of the message?
    Thanks.

    Reply
  2. pedrofelix Post author

    The serialization/deserialization stage happens inside the operation handlers stage, performed by specific handlers. I will give more info about this on a future post. Until then, check the RequestContentHandler and ResponseContentHandler classes

    Reply
  3. Pingback: WCF Web API–Description Model « Pedro Félix’s shared memory

  4. Jonathan

    Now I get… finally after 24 hours of WCF Web api research. In other online tutorials the Microsoft team is failing to explain the essential API mechanism. The WCF Web API beginner is not interested multi media handler tricks or Google mail interfaces or simplistic read-only RESTfull api’s.

    Pedro if you need an idea for a future article in this series how about an “API examples 101” showing how to handle different method parameters for a regular Northwind style web shopping api?

    Reply
    1. pedrofelix Post author

      Could you clarify “method parameters for a regular Northwind style web shopping api”?

      Pedro

      Reply
  5. Jonathan

    Pedro I feel WCF Web api beginners would benefit from a ton of simple examples showing how different parameter types can be passed in and returned. For example one of the most useful LINQ sites for me is LINQ 101 where I can usually find an example of what I suspect LINQ might be capable of.

    The problem with the promotional WCF Web api material on the web today is that it either presents the project as an evolution to pure WCF (which assumes prior knowledge of WCF) or the articles try to demonstrate the problem solving reach of WCF Web api resulting to too much coverage of edge case stuff like media handling and ODATA.

    The key to the success of WCF Web api is the “api” bit or put another way HTTP POST oriented RPC. But at this point in time I cannot find one useful starter project on the net that demonstrates how to expose a complex application interface using the technology.

    Reply
  6. pedrofelix Post author

    Hi Jonathan,

    Thanks for your comments.
    My interest in WCF Web API is mainly on two areas:
    1) Understand its internal architecture, namely its extensibility points and how it integrates with the WCF architecture.
    2) Learn how to develop systems using the ReST architectural style.
    Until now, my posts have focused on 1). Regarding 2), I still have a long learning road ahead but I want to start sharing my ideas on the subject.
    I’m really not interested in using WCF Web API with an RPC style architecture.

    Reply
  7. Jonathan

    No problem Pedro. My post was really a poke at Microsoft. Your blog entries about Web api are one of the best resources on the subject so I assumed, by mistake, that you were part of Microsoft.

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s