Home Web Development Mastering ServiceStack

Mastering ServiceStack

By Andreas Niedermair
books-svg-icon Book
eBook $39.99 $27.98
Print $48.99
Subscription $15.99 $10 p/m for three months
$10 p/m for first 3 months. $15.99 p/m after that. Cancel Anytime!
What do you get with a Packt Subscription?
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats, plus a monthly download credit
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with video?
Stream this video
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
What do you get with Exam Trainer?
Flashcards, Mock exams, Exam Tips, Practice Questions
Access these resources with our interactive certification platform
Mobile compatible-Practice whenever, wherever, however you want
BUY NOW $10 p/m for first 3 months. $15.99 p/m after that. Cancel Anytime!
eBook $39.99 $27.98
Print $48.99
Subscription $15.99 $10 p/m for three months
What do you get with a Packt Subscription?
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats, plus a monthly download credit
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with video?
Stream this video
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
What do you get with Exam Trainer?
Flashcards, Mock exams, Exam Tips, Practice Questions
Access these resources with our interactive certification platform
Mobile compatible-Practice whenever, wherever, however you want
About this book
Publication date:
October 2015
Publisher
Packt
Pages
216
ISBN
9781783986583

 

Chapter 1. Distributed Systems and How ServiceStack Jumps in

ServiceStack is a powerful web service framework and it offers many possibilities. ServiceStack's adaptive nature makes the components of the framework fine-grained, which makes it crucial to understand the layout and its components:

  • ServiceStack: Lets you create your own service endpoint.

  • ServiceStack.Interfaces: It holds all the base interfaces that are used for the dependency injection-driven internals of ServiceStack. You can fully customize ServiceStack by implementing and registering one of these interfaces.

  • ServiceStack.Text: In this namespace reside various serialization utilities for JSON, JSV, and CSV. It also offers dynamic JSON processing, diagnostic extensions for printing a formatted dump of an object, URL extensions to deal with the common issues, such as encoding and decoding, stream extensions, and many more.

  • ServiceStack.Client: It contains the relevant clients to connect and consume JSON, XML, JSV, SOAP, and MQ services.

  • ServiceStack.Caching: It holds provider-specific endpoints that can be injected as caching storage (InMemory, Redis, Aws, Azure, Memcached, OrmLite …).

  • ServiceStack.OrmLite: It contains a fast micro-ORM with adapters for popular RDMBS, such as the SQL Server, MySQL, PostgreSQL, SQLite, and many others.

  • ServiceStack.Redis: It holds .NET's leading client for Redis, an open source and advanced key-value store.

  • ServiceStack.Authentication: It provides various authentication providers, such as OAuth, OAuth2, OpenID, in combination with its storage providers, such as OrmLite and NHibernate.

  • ServiceStack.Logging: This includes adapters for many logging frameworks such as Elmah, NLog, Log4Net, and EventLog to provide an interchangeable and loosely coupled logging experience.

  • ServiceStack.Razor: It lets you add a Razor view engine to your web service to provide a single stack implementation of your service and front-end.

  • Various other components, such as extensions to formats (ServiceStack.MsgPack and ServiceStack.Protobuf), web service client frameworks, such as ServiceStack.Api.Swagger, a bundler for web resources (ServiceStack.Bundler), a compiler for cross-platform native Desktop applications (ServiceStack.Gap), and many others.

Note

As the NuGet package names often do not match the namespaces within, the NuGet package names are mentioned separately.

Additionally, ServiceStack offers tools that are focused on simplicity and performance, so (development-) time can be spent on a hassle-free usage. This feature makes it a great alternative to Windows Communication Framework (WCF) and others.

Note

Note that some components are dependency free, such as ServiceStack.Text and ServiceStack.Client, which do not call for a coupled usage with ServiceStack.

One of the big ideas behind ServiceStack is the Code-First approach. Before you start to design your database, you should focus on the domain design and its Plain Old CLR Objects (POCOs), which then can be used through the components of your stack:

  • In Request and Response DTOs

  • In client projects by leveraging a shared assembly

  • As data models in your database

  • As entities in your cache and session

  • In serializers and configurations

Tip

If you ever find the need to apply ServiceStack to an existing database, it will be trivial to derive your POCOs from the database schema, especially, if you are dealing with a large pre-existing database and coupled usage in the codebase. Therefore, you can use T4 scripts that are bundled with ServiceStack.OrmLite, to code-gen your POCOs. You can find these at https://github.com/ServiceStack/ServiceStack.OrmLite/tree/master/src/T4.

 

A message-based service


If you have previously used Web API or Windows Communication Framework (WCF) you will find yourself in the habit of writing service methods specialized for only one scenario.

A typical interface to search through Task instances would be something, like the following:

public class Task
{
  public int Id { get; set; }
  public string Title { get; set; }
  public int UserId { get; set; }
}
interface IService
{
  Task GetTaskById(int id);
  Task[] GetAllTasks();
  Task[] GetTasksById(int[] ids);
  Task[] GetTasksForUserId(int userId);
  Task[] GetTasksByTitle(string title);
  Task[] GetTasksByTitleForUserId(string title, int userId);
}

There is basically a separate and specialized method for each search option.

In contrast, according to the message pattern, this would be implemented as follows:

public class FindTasks : ServiceStack.IReturn<Task[]>
{
  public int[] Ids { get; set; }
  public int[] UserIds { get; set; }
  public string Title { get; set; }
}

Note

Additionally, to the basic definition of the message, ServiceStack.IReturn<T> is already used here. There is no need whatsoever to implement this interface, but doing so for example gives you the possibility to deviate from the naming convention of ResponseDTO class names for the metadata page, and defines the return type on service clients Send methods.

This combines the various search options into one message, which makes the following benefits obvious:

  • Less distribution of logic

  • Less maintenance due to less code duplication in the long run

  • Easily add more functionality by introducing new properties in the message without adapting to existing usages that gives you a straightforward approach to various versions

  • Less friction with caching, as the instances can be used to generate a cache key

  • Easy to serialize and log

  • When immutable, it's perfect for concurrency and multithreaded scenarios

To show these benefits in action, let's contrast the implementations, which are by no means optimized or perfectly well implemented:

public class Service : IService
{
  Task[] _tasks = new []
  {
    new Task { Id = 1, Title = "Task 1", UserId = 1 },
    new Task { Id = 2, Title = "Task 2", UserId = 2 },
    new Task { Id = 3, Title = "Task 3", UserId = 3 }
  };

  public Task GetTaskById(int id)
  {
    return this._tasks.FirstOrDefault(arg => arg.Id == id);
  }

  public Task[] GetAllTasks()
  {
   return this._tasks;
  }

  public Task[] GetTasksById(int[] ids)
  {
   return this._tasks.Where(arg => ids.Contains(arg.Id)).ToArray();
  }

  public Task[] GetTasksForUserId(int[] userIds)
  {
   return this._tasks.Where(arg => userIds.Contains(arg.UserId).ToArray();
  }

  public Task[] GetTasksByTitle(string title)
  {
    return this._tasks.Where(arg => arg.Title.Contains(title)).ToArray();
  }

  public Task[] GetTasksByTitleForUserId(string title, int userId)
  {
    return this._tasks.Where(arg => arg.Title.Contains(title) && arg.UserId == userId).ToArray();
  }
}

This basic Service class holds an array of Task objects that are used in every method for the specific query. Then the matching excerpt of the array is returned.

In a message-based service it would look like:

public partial class TaskService : ServiceStack.IService, ServiceStack.IAny<FindTasks>
{
  Task[] _tasks = new []
  {
    new Task { Id = 1, Title = "Task 1", UserId = 1 },
    new Task { Id = 2, Title = "Task 2", UserId = 2 },
    new Task { Id = 3, Title = "Task 3", UserId = 3 }
  };

  public object Any(FindTasks request)
  {
    // we could generate a hash of the request and query
    // against a cache
    var tasks = this._tasks.AsQueryable();

    if (request.Ids != null)
    {
      tasks = tasks.Where(arg => request.Ids.Contains(arg.Id));
    }
    if (request.UserIds != null)
    {
      tasks = tasks.Where(arg => request.UserIds.Contains(arg.UserId));
    }

    if (request.Title != null)
    {
      tasks = tasks.Where(arg => arg.Title.Contains(title));
    }

    // here is room to implement more clauses
    return tasks;
  }
}

The implementation of the actual endpoint is straightforward, just apply each filter prior to checking against null and return a matching excerpt.

Note

The added ServiceStack.IAny<T> naturally forces an implementation of the request in the TaskService class. You can still add your operation to the service manually, but I strongly advise you to follow the New API outline available at https://github.com/ServiceStack/ServiceStack/wiki/New-API.

This implementation can be easily connected to the following web page. It once again shows the power of the Code-First approach as it binds to the following interface with ease:

 

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 processing

    • ServiceStack.AppHostListenerPoolBase, ServiceStack.AppSelfHostBase and ServiceStack.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:

  1. 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.

  2. All the delegates added to the PreRequestFilters property are executed, which cannot access the RequestDTO yet though.

  3. The content (Query String, Form Data, POST payload …) is deserialized into the RequestDTO either by default binding or a custom RequestBinder predicate.

  4. All delegates added to the RequestConverters collection are executed.

  5. All the RequestFilterAttribute annotations with a Priority less than zero are executed.

  6. All the delegates added to the GlobalTypedRequestFilters property and GlobalRequestFilters property are executed.

  7. All the RequestFilterAttribute annotations with a Priority greater than or equal to zero are executed.

  8. All delegates added to the ResponseConverters collection are executed.

  9. Then the registered ServiceStack.Web.IServiceRunner object calls OnBeforeExecute, your service method, OnAfterExecute and HandleException.

  10. All the ResponseFilterAttribute annotations with a Priority less than zero are executed.

  11. All the delegates added to the GlobalTypedResponseFilter property and GlobalResponseFilters property are executed.

  12. All the ResponseFilterAttribute annotations with a Priority greater than or equal to zero are executed.

  13. Finally OnEndRequest and OnEndRequestCallback 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:

  1. All delegates added to the RequestConverters collection are executed.

  2. First all the delegates added to the GlobalTypedMessageRequestFilters property and GlobalMessageRequestFilters property are executed.

  3. Then the registered ServiceStack.Web.IServiceRunner object calls OnBeforeExecute, your service method, OnAfterExecute and HandleException.

  4. All delegates added to the ResponseConverters collection are executed.

  5. All the delegates added to the GlobalTypedMessageResponseFilter property and GlobalMessageResponseFilters property are executed.

  6. 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.

 

A brief history of distributed systems


In the beginning of software architecture there were monolithic systems, they had data access codes and business logic combined in the user-interface code. There was no possibility for modularity to exchange layers (for example when the DBMS changes) or the option to reuse components in other applications.

The first change to this architecture was the introduction of layers, specialized on certain concerns of the design. It brought many benefits, such as exchangeability and testability of layers. The execution and deployment is still bound to a single logical executable thought; hence, it can still be called a monolithic kind.

The next adaption to this design was to add interoperability; with the introduction of a public API external process have the possibility to communicate with the application. This can be done by providing a proprietary or customized message format through protocols, such as .NET Remoting, WCF, sockets, and many others.

Nowadays, the trend of designing applications as a suite of fine-grained services is called microservices, which is based on the main idea to orchestrate a bigger system with single-responsibility services. This idea has become more or less standard in the design of Enterprise Applications over the last decade.

The technologies used in the single services are independent, providing the possibility for specialized teams and segregation of internal dependencies. For example, the clients of a data service do not need any information on the actual DBMS, neither do they have a dependency on the used database-specific framework such as NHibernate. The design problems of a single application can be solved in microservices by scaling the services with high demand, which also brings reliability, and then deploying them in a version affine manner to not break usages. This approach also gives you the opportunity to use the tools that fit the concern of the service in the best way, whether it be the programming language or the machine they are running on.

The design principles of an API

With all this "uncontrolled growth" of services, managed by potentially different teams with different tools with different "thinkings", comes the need for a unified style or a set of the base design guidelines of the internal and external APIs. There are many resources available regarding this issue, I will cover the most important thoughts, which are discussed further in this chapter.

Usage convenience

Usually, you are defining an interface for an end user with limited technological knowledge. With services, the audience are programmers, which gives you a technical affine counterpart who may come up with every little flaw in your design. One of the main goals in the design process is to keep it simple, frictionless and understandable to the absolute maximum. Verify the simplicity of the design by letting new people try your API, gather feedback and make the usage a straightforward scenario. Also, avoid the introduction of additional dependencies and unnatural bindings to use your service.

Following a message based communication gives you a top-notch and solid base for solving the design process.

Documentation

This may only apply to external APIs, but should also be considered for internal ones. Provide example requests and responses, as well as documentation of the DTOs. ServiceStack provides a metadata page to document the requests and responses that also serves as the base for Swagger. You can also add documentation and example code to the operations with Razor views, which is covered in Chapter 5, Documentation and Versioning.

Consistency

Keep old versions of your API as long as they are needed to ensure that there is no break in the usages. Be consistent with the naming of properties (also take naming practices of the technologies used by clients into account), endpoints, and formats and ultimately push a changelog to ease migration of changes.

The usage of versions is covered in Chapter 5, Documentation and Versioning.

Robustness

One of the main benefits of using ServiceStack for your service is that you can deal with various input and output formats: You can use QueryString, POST-payload, form-data and even extend this by adding your own format for inputting data. ServiceStack also bundles different output formats and can be enhanced with customized content types.

The format binding is done according to either the value of the Content-Type HTTP header or query string overrides. If you want to implement your own format, you can do so by implementing your own format:

public override void Configure(Container container)
{
  this.ContentTypes.Register("application/X-myformat",
    (req, response, stream) =>
    {
      // TODO add your serialization logic
    },
    (type, stream) =>
    {
      // TODO add your deserialization logic
    });
}

Attach validation to your requests as well to provide comprehensible reasons for a failed communication, which is covered in Chapter 5, Documentation and Versioning.

Authentication, authorization, and security

Before any other point on the checklist, there's the encryption of the transport layer with the incorporation of SSL for external services.

Processing a request should always capture the following aspects:

  • Validate the input

  • Authenticate the consumer

  • Check authorization to the operation

  • Check authorization to the resource of the operation

Authentication can also serve as a base to limit resources for a consumer as well as a common starting point to troubleshoot issues.

ServiceStack also provides several ways to implement authentication and authorization to your service with various providers, which is covered in Chapter 2, ServiceStack as Your Unique Point of Access.

Note

For further information on a lovable API design please read Web API Design – Crafting Interfaces that Developers Love by Brian Mulloy, which can be downloaded at http://apigee.com/about/resources/ebooks/web-api-design.

 

Problems with distributed systems


The design approach of distributed systems is by no means a silver-bullet and introduces new problems or magnifies existing ones. I am going to discuss some higher level problems and leave out the low level issues, such as transportation issues (package loss, network latency), to focus on the stack of a typical software engineer.

Complexity in design

As such systems consist of many endpoints, we have new challenges to worry about.

A broader set of skills

Bringing a distributed system to life requires extensive skills within the development team, as well as the operational team. Adding new dependencies to single services also needs a distributed understanding of the components involved, to keep the system vital and to be able to respond to requests in a reasonable time.

Testing

Before you ship a system it needs to be tested. Testing does not stop with a single service, but is done for the complete environment, which becomes challenging when you need to ensure the consistency of the environment for manual and automated testing. Differences between staging systems and live systems, such as different framework versions, can also be a problem.

A pragmatic approach in the long run is to incorporate monitoring to easily spot anomalies in the flow of operations, as bugs can have amplified repercussions on the system.

Rollout

The rollout of such a dynamic environment should be done by a fully automated deployment process, leaving as little room as possible for manual faults.

Operating overhead

Splitting a monolith into multiple processes may start with a certain number of service instances. When applying a failover protection or load balancing and messaging, it becomes a really challenging task to keep such a system running, as the number of instances can easily increase.

Tracing

In a distributed system, one can not simply solve an issue by inspecting a process. You will have multiple places for log files that need a correlative identifier to track down a request and its problems.

There are many solutions out there to help you to manage and centralize logging.

Contracts

To ensure valid communication between two services, you need a contract for a message format and a basic understanding of it. Any one-sided change to this contract will result in a break, therefore we need a coordinated way of releasing it.

A basic solution to this problem is the introduction of versions to the messages, which is basically a method to introduce backward compatibility to the system. As we all know, business sometimes calls for partial rollouts that render components out of sync and "versions" are no longer the magic bullet in such a case.

Issues at runtime

We might come across many issues while running our system that we need to learn from their huddles and perfect our system. Here are some of the problems we might face:

(Un)atomicity of operations

An operation in a distributed system is by no means guaranteed to be atomic, as it might be split into several subtasks that can be executed in parallel or sequentially across service borders.

This calls for a certain mechanism of distributed transactions, to revoke preceding actions when an essential subtask failed. This can also be achieved by queuing entities in a staged pool and releasing them to the live system when all the operations are successfully applied, or otherwise invalidate the changes.

A shared register

When multiple components share the same entity, such as credentials, there is a need to synchronize the register to have the same data available in multiple processes and to minimize hard faults, which fall back to a common database. Another issue originates in the asynchronous behavior of such systems, making it vulnerable to lost updates, which happens when component A and component B are updating the same entity.

If the components do not have a shared register but rather solve this issue by implementing synchronization, there is a need to introduce a notification upon changes.

Performance

Besides the performance of a single service, there's a natural overhead in the communication when you have to marshal the request and response instead of just working on a reference in the same process.

It is important to not base this process on blindfolded guessing when trying to resolve a bottleneck, which is wrong most of the time. It's better to base it on investigation even if it is hard to apply in a distributed system.

Methods for inspecting performance is covered in Chapter 4, Analyzing and Tuning a Distributed System.

 

Summary


In this chapter the available components of ServiceStack were introduced, to give a crisp overview of the framework itself. In addition to this, we are now familiar with the basic concepts of ServiceStack, such as Code-First and the message pattern. We dove a little bit deeper into the processing chain and explored multiple hooks for injections. Finally, we spoke about design principles of an API and uncovered the problems with distributed systems.

In the next chapter we will introduce dependency injection, which lays the base for a hands-on scenario. Furthermore, we will cover sessions and caching, and add authentication and authorization to our working demo.

About the Author
  • Andreas Niedermair

    Andreas Niedermair is a .NET developer who is rooted in the web fraction (and still affiliated with it). He has worked in numerous enterprise environments building leading industry solutions and has also contributed to the open source community. He is always striving for a deeper understanding of technology to stay on the cutting edge. He contributed to the ServiceStack 4 Cookbook as a technical reviewer and has held lectures for non-profit associations. You can contact Andreas at http://andreas.niedermair.name.

    Browse publications by this author
Latest Reviews (2 reviews total)
Utile strumento di lavoro.
Mastering ServiceStack
Unlock this book and the full library FREE for 7 days
Start now