The processing chains of ServiceStack
The ServiceStack services can be hosted in an HTTP and Message Queue context, hence there are two different processing chains, which will be covered in the following two sections.
We will also cover request and response filters and annotations later in the chapter, which allow you to apply late-bound changes to your requests and responses.
HTTP context
The following contexts and their base classes are all derived from ServiceStack.ServiceStackHost
; they can be used for your HTTP hosted service:
- ASP.NET
ServiceStack.AppHostBase
- Self-hosted
ServiceStack.AppHostListenerBase
for single-threaded processingServiceStack.AppHostListenerPoolBase
,ServiceStack.AppSelfHostBase
andServiceStack.AppHostListenerSmartPoolBase
for multithreaded processing, where the former is utilizing the .NET Thread Pool and the others Smart Thread Pool (https://smartthreadpool.codeplex.com/) for queuing their work items
The pipeline is the same for every scenario, as shown in the following diagram:
Before any request goes into the ServiceStack pipeline, the functions in your AppHost's RawHttpHandlers
are executed and the result is in the favor of further processing in ServiceStack if the value is not null. The processing in ServiceStack is done in the following order:
- The path is checked against existing routes (by attribution and convention). If none is matching, the delegates added to the
CatchAllHandlers
property are used for probing. - All the delegates added to the
PreRequestFilters
property are executed, which cannot access the RequestDTO yet though. - The content (Query String, Form Data, POST payload …) is deserialized into the RequestDTO either by default binding or a custom RequestBinder predicate.
- All delegates added to the
RequestConverters
collection are executed. - All the
RequestFilterAttribute
annotations with aPriority
less than zero are executed. - All the delegates added to the
GlobalTypedRequestFilters
property andGlobalRequestFilters
property are executed. - All the
RequestFilterAttribute
annotations with aPriority
greater than or equal to zero are executed. - All delegates added to the
ResponseConverters
collection are executed. - Then the registered
ServiceStack.Web.IServiceRunner
object callsOnBeforeExecute
, your service method,OnAfterExecute
andHandleException
. - All the
ResponseFilterAttribute
annotations with aPriority
less than zero are executed. - All the delegates added to the
GlobalTypedResponseFilter
property andGlobalResponseFilters
property are executed. - All the
ResponseFilterAttribute
annotations with aPriority
greater than or equal to zero are executed. - Finally
OnEndRequest
andOnEndRequestCallback
is called and the response is written to the HTTP stream.
Message Queue context
The following MQ server implementations are available (the packages are listed in brackets for easier searching on NuGet) for your ServiceStack service:
ServiceStack.RabbitMq.RabbitMqServer
(ServiceStack.RabbitMq
)ServiceStack.Messaging.Redis.RedisMqServer
(ServiceStack.Server
)ServiceStack.Messaging.Redis.RedisTransientMessageService
(ServiceStack.Server
)ServiceStack.Messaging.Rcon.Server
(ServiceStack.Server
)ServiceStack.Messaging.InMemoryTransientMessageService
(ServiceStack)
Note
The specific messaging implementations are described in detail in Chapter 3, Asynchronous Communication between Components.
In contrast to the processing chain of an HTTP context, the steps in an MQ context are as follows:
- All delegates added to the
RequestConverters
collection are executed. - First all the delegates added to the
GlobalTypedMessageRequestFilters
property andGlobalMessageRequestFilters
property are executed. - Then the registered
ServiceStack.Web.IServiceRunner
object callsOnBeforeExecute
, your service method,OnAfterExecute
andHandleException
. - All delegates added to the
ResponseConverters
collection are executed. - All the delegates added to the
GlobalTypedMessageResponseFilter
property andGlobalMessageResponseFilters
property are executed. - Finally the response is returned to the MQ.
Tip
Some ServiceStack MQ server classes provide customized hooks to filter requests and responses, giving you specialized possibilities to customize your pipeline.
In contrast to this, you can easily combine an MQ service and an HTTP service and leverage a trimmed-down processing pipeline of the HTTP service. This is possible as one of the core concepts of ServiceStack is the Message Pattern, which comes quite handy in this scenario:
public class AppHost : ServiceStack.AppSelfHostBase { public AppHost() : base ("Ticket Service", typeof (TaskService).Assembly) { } public override void Configure(Funq.Container container) { var messageService = container.Resolve<ServiceStack.Messaging.IMessageService>(); messageService.RegisterHandler<FindTasks> (this.ServiceController.ExecuteMessage); messageService.Start(); } }
The preceding code relies on the registration of a ServiceStack.Interfaces.IMessageService
implementation, which gets resolved inside the Configure
method. Then all the plumbing is done to register the handlers and start the MQ client.
If you do not want to provide an HTTP endpoint but still use the internals of ServiceStack such as the powerful IoC-Container, which is an unusual common use-case, you can use the generic BasicAppHost
for an extended processing pipeline such as:
var basicAppHost = new ServiceStack.Testing.BasicAppHost(typeof(TaskService.Assembly)) { ConfigureAppHost = host => { var messageService = host.Container.Resolve <ServiceStack.Interfaces.IMessageService>(); messageService.RegisterHandler <FindTasks>(host.ServiceController.ExecuteMessage); messageService.Start(); } };
This is especially helpful in testing scenarios, where you want to deal with the endpoints directly.
Note
The other hook to configure your service is ConfigureContainer
, which is executed after ConfigureAppHost
. You need to be aware of this order when you are trying to resolve any dependency, as configuring the container is done afterwards.
Tip
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.