SOA and DDD are two important idioms for architecture of modern systems. I do not know if there is one commonly shared understanding of SOA. The problem with SOA is that it is quite abstract and void of implementation details. Martin fowler has summarized this ambiguity quite well. To not muddy the water even more I would avoid the term SOA as much as possible. The fun doesn't stop here though. Domain driven design also uses "service" to signify an interface* to the domain model. Its extremely important to clear the confusion and name the related terms important for this book's purpose. I do feel guilty to throw new terms but I don't have a choice. There are three types of services: External Interface Service, Application Service and Domain Service.
External Interface Service
As the name suggests, this is the thin layer which is responsible for exposing the application to other applications within or outside the same system. In this layer the remoting, transport protocol, versioning concerns are handled generally by using platform infrastructure. The web services layer, as commonly understood, falls in this category. It is quite possible that application service can be annotated to be used as external internal service.
Application Service
A web application code can be divided into two parts. The user interface code and the business logic code on which the former depends. While this really is an abstraction, but is quite vital one. While with other abstractions in a web application are geared towards separation of concern and decoupling, business logic from user interface separation also allows much sought after "code reuse". Such abstractions can be also used for functional testing, data migration and web services. We would see examples of all of these in this book. The topmost layer of business logic code is called application service.
Since application service deals with business logic, it picks up all the query and command processing related responsibilities from the controller. Controller is only responsible for presentation behavior like page navigation, handling web-request, web-response and user-session. Application service hence is a stateless abstraction leaving handling of state to the consuming layers. This layer is very similar to service-facade layer in the DDD world, although this isn't a formal definition. We would revisit the application service again in the context of domain modules. The objects which application service exposes
Domain service
Service as defined in DDD is broken down into application service and domain service. In most applications there are a lot of simple query processing which primarily geared towards retrieving the persistent data and presenting it. Assembling all this data from different repository is something which is done by application service in most cases, as it doesn't involve execution of business logic. Application service collaborates with the repositories to load the domain objects and present it via its public API. Query processing might involve domain validations and performing performing business logic on retrieved data before they can be presented. The application service delegates such responsibility to the domain service.
Command processing works in somewhat similar fashion for validations. Application service hands over the responsibility to domain service after performing the validation. The domain service uses the repository to retrieve/save the domain objects and invoke business operations on the same.
Decoupled domain model works very well with distinct application and domain service. Domain service is completely agnostic of application contract objects. This constraint helps in dividing responsibility between these layer of services.
Different implementation might choose to use same layers to play multiple roles.
Application Service Test
* not as in Java/C# interfaces
Domain service layer should hide as many calls to repository as possible from the application service layer.