CHAPTER 3
In the previous chapter, we went through the basics of ServiceStack—what it is and which functionalities it supports.
In this chapter, we will spend some time carefully building our domain model and explaining what we want to achieve with the service we build. It’s very important to understand the various parts in this chapter because the implementation that follows in Chapter 5 will be much clearer.
In order to demonstrate the usage of ServiceStack with a concrete example, we will create a simple order management system which will be far from complete but good enough for getting started.
The order management system will be implemented by three RESTful web services that will enable its clients to:
The order management service will then be expanded, and more features and functionalities will be added, such as authentication, validation, and dependency injection, just to name a few.
The object model tries to be simple. At its heart, there are only a few classes: Order, OrderItem, Product, and Status.
One Order contains a list of OrderItems. The Id of an order is automatically generated by the system. The Version field is a special field that can be used to manage the optimistic concurrency when saving data to the repository—a topic which is beyond the scope of this book. An Order can be Active or Inactive, and this is reflected through its Status.
An item represents part of an order; it can be any food or beverage (e.g., pizza, beer, or coffee). An item contains a reference to a Product and has a Quantity attribute.
A Product represents a part of the Order and it’s a reference class. A Product can be Active or Inactive, and this is reflected through its Status.
The Status class is a reference data class. In our application, it will have only two possible statuses: Active and Inactive.
public class Order { public int Id { get; set; } public bool IsTakeAway { get; set; } public DateTime CreationDate { get; set; } public List<OrderItem> Items { get; set; } public Status Status { get; set; } public int Version { get; set; } }
public class OrderItem { public int Id { get; set; } public Product Product { get; set; } public int Quantity { get; set; } public int Version { get; set; } } public class Product { public int Id { get; set; } public string Name { get; set; } public int Version { get; set; } public Status Status { get; set; } } public class Status { public int Id { get; set; } public string Name { get; set; } } |
The service exposed has to define a very clear Uniform Resource Identifier (URI) structure and the respective HTTP verbs. Keep in mind that not all the verbs need to be implemented, but we choose what is appropriate.
Table 5 lists the operations exposed by the OrderService.
URI | HTTP Verb | Description |
|---|---|---|
/orders | GET | Gets the full list of all orders and respective items. |
/orders | POST | Creates a new order. |
/orders/1234 | GET | Gets the details of a single order. |
/orders/1234 | PUT | Updates an existing order. |
/orders/1234 | DELETE |
The web service OrderItemService exposes operations related to the Order’s Items collection as shown in Table 6.
URI | HTTP Verb | Description |
|---|---|---|
/orders/1234/items | GET | Gets a full list of items assigned to an order. |
/orders/1234/items/1 | GET | Gets an item assigned to a specific order. |
ProductService exposes operations related to the Product object as shown in Table 7.
URI | HTTP Verb | Description |
|---|---|---|
/products | GET | Gets a full list of all available products. |
/products | POST | Creates a new product. |
/products/1234 | GET | Gets the details of a single product. |
/products/1234 | PUT | Updates an existing product. |
/products/1234 | DELETE | Deletes an existing product. |
For the examples to be very short, we won’t deal with any data access code in this book. All pseudo-database communication will go through specific repositories[20] (OrderRepository, ProductRepository). Therefore, we will handle our orders in memory.
Instances of the repositories will be directly injected at run time to the specific web service by using ServiceStack’s default Funq IoC container.
There are many ways to keep the assemblies separated, and this usually depends on the project’s needs. When working with services, I usually apply the following three rules:

ServiceStack.Succinctly.Host is the entry point of the application and the only component that communicates with the client. It contains the exposed services and all of the necessary plumbing, routing, instrumentation, etc. This is exactly where we are going to use the ServiceStack framework functionalities.
ServiceStack.Succinctly.ServiceInterface contains Request and Response DTOs. This library can be directly shared with the client application to ease the communication and transformation of data. This library shouldn’t contain any application logic.
OrderManagement.Core contains the domain model of the application and the required business logic, application logic, etc.
OrderManagement.DataAccessLayer contains the logic to access the database and the related repositories.