ASP.NET Web API Processing Architecture
This post presents a first overview of the ASP.NET Web API processing architecture: what happens since a HTTP request is received until a response is produced.
The ASP.NET Web API processing architecture, represented in the following diagram, is composed by three layers: hosting, message handler pipeline and controller handling.
The lower layer is responsible for the Web API hosting, i.e., the interface between Web API and an underlying HTTP handling runtime. Succinctly, this layer is responsible for creating HttpRequestMessage instances, and then pushing them into the upper message handler pipeline. The hosting layer is also responsible for processing the HttpResponseMessage returned back from this handler pipeline.
Currently, there are two “out-of-the-box” hosting options: self-hosting and web hosting, i.e., hosting on top of the ASP.NET classical pipeline.
Self-hosting is based on a pump that retrieves WCF Message instances from a WCF channel stack, converts them into HttpRequestMessage instances and then push those into the upper message handler pipeline.
The Web API hosting is not limited to these two options. There are already some additional hosts, contributed by the community:
- Louis DeJardin created a host on top of OWIN.
- I’ve created a host based on the Azure Service Bus relaying.
Message Handler Pipeline
The middle layer is composed by a message handler pipeline, similar to the one that existed on WCF Web API. This pipeline is exposed by the HttpServer class, which also extends HttpMessageHandler (composite pattern).
This pipeline provides the extensibility point for “middleware” addressing cross-cutting concerns such as: logging, HTTP authentication, HTTP method translation, …
The presence of this HttpControllerDispatcher is only required when using the controller-based programming model (ApiController derived classes). It is also possible to mount a completely different model, just by replacing the pipeline’s top message handler.
Finally, the upper layer corresponds to the controller specific processing, namely:
- Action selection;
- Filter execution;
- Model binding;
- Action invocation;
- Response content creation via formatters.
Future posts will address each one of this layers in more details. Until then, feel free to use the comments.