Поделиться через


Chapter 25: Designing Service Applications

For more details of the topics covered in this guide, see Contents of the Guide.

Contents

  • Overview
  • General Design Considerations
  • Specific Design Issues
  • Technology Considerations
  • Deployment Considerations
  • Relevant Design Patterns
  • Additional Resources

Overview

In this chapter, you will learn about the nature and use of services, the general guidelines for different service scenarios, and the key attributes of services. You will also see guidelines for the layers within a services application, and key factors you must consider in terms of performance, security, deployment, patterns, and technology considerations.

A service is a public interface that provides access to a unit of functionality. Services literally provide some programmatic service to the caller, who consumes the service. Services are loosely coupled and can be combined within a client, or combined within other services, to provide functionality that is more complex. Services are distributable and can be accessed from a remote machine as well as from the machine on which they are running. Services are message-oriented, meaning that service interfaces are defined by a Web Services Description Language (WSDL) file, and operations are called using Extensible Markup Language (XML)-based message schemas that are passed over a transport channel. Services support a heterogeneous environment by focusing interoperability at the message/interface definition. If components can understand the message and interface definition, they can use the service regardless of their base technology. Figure 1 shows an overall view of a typical services application architecture.

Ee658114.b3f20583-6f12-43b9-82d9-4b020fbc669b(en-us,PandP.10).png

Figure 1

A common services application architecture

A typical services application is composed of three layers: the service layer, business layer, and data layer. The service layer may include service interfaces, message types, and data types components; the business layer may include business logic, business workflow, and business entity components; and the data layer may include data access and service agent components. For more information about layered design, see Chapter 5, "Layered Application Guidelines." For more information about the components appropriate for each layer, see Chapter 10 "Component Guidelines."

Services are flexible by nature and can be used in a wide variety of scenarios and combinations. The following are typical scenarios:

  • Service exposed over the Internet. This scenario describes a service that is consumed by a range of clients over the Internet. This scenario includes business-to-business as well as consumer-focused services. A stockbroker Web site that consumes Web services from stock exchanges and provides stock quotes would be an example of this scenario. Decisions on authentication and authorization must be based on Internet trust boundaries and credentials options. For example, user name and password authentication or the use of certificates is more likely in the Internet scenario than the intranet scenario.
  • Service exposed over an intranet. This scenario describes a service that is consumed over an intranet by a (usually restricted) set of internal or corporate clients. An enterprise-level document management application would be an example of this scenario. Decisions on authentication and authorization must be based on intranet trust boundaries and credentials options. For example, Windows authentication using Active Directory is more likely to be the chosen user store in the intranet scenario than in the Internet scenario.
  • Service exposed on the local machine. This scenario describes a service that is consumed by an application on the local machine. Transport and message protection decisions must be based on local machine trust boundaries and users.
  • Mixed scenario. This scenario describes a service that is consumed by multiple applications over the Internet, an intranet, and/or the local machine. A line-of-business (LOB) service application that is consumed internally by a rich client application and over the Internet by a Web application would be an example of this scenario.

General Design Considerations

When designing service-based applications, you should follow the general guidelines that apply to all services such as designing for coarse-grained operations, honoring the service contract, and anticipating invalid requests or requests that arrive in the wrong order. In addition to the general guidelines, there are specific guidelines that you should follow for different types of services. For example, with a Service-Oriented Architecture (SOA), you should ensure that the operations are application-scoped and that the service is autonomous. Alternatively, you might have an application that provides workflow services, or you might be designing an operational data store that provides a service-based interface. Consider the following guidelines when designing service applications:

  • Consider using a layered approach to designing service applications and avoid tight coupling across layers. Separate the business rules and data access functions into distinct components where appropriate. Use abstraction to provide an interface into the business layer. This abstraction can be implemented by using public object interfaces, common interface definitions, abstract base classes, or messaging. For more information about abstraction in layered architecture, see Chapter 5 "Layered Application Guidelines."
  • Design coarse-grained operations. Avoid chatty calls to the service interface, which can lead to very poor performance. Service operations should be coarse-grained and focused on application operations. Consider using the Façade pattern to package smaller fine-grained operations into single coarse-grained operations. For example, with demographics data, you should provide an operation that returns all of the data in one call instead of requiring multiple calls that return subsets of the data.
  • Design data contracts for extensibility and reuse. Data contracts should be designed so that you can extend them without affecting consumers of the service. When possible, compose the complex types used by your service from standard elements. The service layer should have knowledge of business entities used by the business layer. Typically, this is achieved by creating a separate assembly that contains business entities, which is shared between the service layer and business layer.
  • Design only for the service contract. The service layer should implement and provide only the functionality detailed in the service contract, and the internal implementation and details of a service should never be exposed to external consumers. Also, if you need to change the service contract to include new functionality implemented by a service, and the new operations and types are not backward compatible with the existing contracts, consider versioning your contracts. Define new operations exposed by the service in a new version of a service contract, and define new schema types in a new version of the data contract. For information about designing message contracts, see Chapter 18 "Communication and Messaging."
  • Design services to be autonomous. Services should not require anything from consumers of the service, and should not assume who the consumer is or how they plan to use the service you provide.
  • Design to assume the possibility of invalid requests. Never assume that all messages received by the service are valid. Implement validation logic to check all messages against the appropriate schemas; and reject or sanitize all invalid messages. For more information about validation, see Chapter 17 "Crosscutting Concerns." Ensure that the service can detect and manage repeated messages (idempotency) by implementing well-known patterns, or by taking advantage of infrastructure services, to ensure that duplicate messages are not processed. In addition, ensure that the service can manage messages arriving out of order (commutativity), perhaps by implementing a design that will store messages and then process them in the correct order.
  • Design services based on policy and with explicit boundaries. A services application should be self contained, with strict boundaries. Access to the service should only be allowed through the service interface layer. The service should publish a policy that describes how consumers can interact with the service. This is particularly important for public services, where consumers can examine the policy to determine interaction requirements.
  • Separate service concerns from infrastructure operational concerns. Crosscutting logic should never be combined with application logic. Doing so can lead to implementations that are difficult to extend and maintain.
  • Use separate assemblies for major components in the service layer. For example, the interface, implementation, data contracts, service contracts, fault contracts, and translators should all be separated into their own assemblies.
  • Avoid using data services to expose individual tables in a database. This will lead to chatty service calls and interdependencies between service operations, which can lead to dependency issues for consumers of the service. In addition, try to avoid implementing business rules within services because different consumers of the data will have unique viewpoints and rules, and this will impose restrictions on the use of the data.
  • Design workflow services to use interfaces supported by your workflow engine. Attempting to create custom interfaces can restrict the types of operations supported, and will increase the effort required to extend and maintain the services. Instead of adding workflow services to an existing service application, consider designing an autonomous service that supports only workflow requirements.

Specific Design Issues

The following sections contain guidelines to help you resolve the common issues that arise as you develop a services architecture:

  • Authentication
  • Authorization
  • Business Layer
  • Communication
  • Data Layer
  • Exception Management
  • Message Construction
  • Message Endpoint
  • Message Protection
  • Message Transformation
  • Message Exchange Patterns
  • Representational State Transfer
  • Service Layer
  • SOAP
  • Validation

Authentication

The design of an effective authentication strategy for your service depends on the type of service host you are using. For example, if the service is hosted in Internet Information Services (IIS), you can take advantage of the authentication support provided by IIS. If the service is hosted by using a Windows Service, you must use message-based or transport-based authentication. Consider the following guidelines when designing an authentication strategy:

  • Identify a suitable mechanism for securely authenticating users, and apply authentication across all trust boundaries. Consider federated services and single sign on (SSO) mechanisms where appropriate.
  • Consider the implications of using different trust settings for executing service code.
  • Ensure that secure protocols such as Secure Sockets Layer (SSL) are used with Basic authentication, or when credentials are passed as plain text. Use secure mechanisms such as Web Services Security (WS-Security) with SOAP messages.

Authorization

Designing an effective authorization strategy is important for the security and reliability of your service application. Failure to design a good authorization strategy can leave your application vulnerable to information disclosure, data tampering, and elevation of privileges. Consider the following guidelines when designing an authorization strategy:

  • Set appropriate access permissions on resources for users, groups, and roles; and apply granular level authorization across all trust boundaries. Execute services under the most restrictive account that is appropriate.
  • Consider using Uniform Resource Locator (URL) authorization and/or file authorization when protecting URL- and file-based resources.
  • Where appropriate, restrict access to publicly accessible service methods using declarative principle permission demands.

Business Layer

The business layer in a services application uses a façade to translate service operations into business operations. The primary goal when designing a service interface is to use coarse-grained operations, which can internally translate into multiple business operations. The business layer façade is responsible for interacting with the appropriate business process components. Consider the following guidelines when designing your business layer:

  • Components in the business layer should have no knowledge of the service layer. The business layer and any business logic code should not have dependencies on code in the service layer, and should never execute code in the service layer.
  • When supporting services, use a façade in the business layer. The façade represents the main entry point into the business layer. Its responsibility is to accept coarse-grained operations and break them down into multiple business operations. However, if your service may be accessed from the local machine or from a client that will not access the service across physical boundaries, you may consider exposing the fine-grained operations as well where this is useful to the client.
  • Design the business layer to be stateless. Service operations should contain all of the information, including state information, which the business layer uses to process a request. Because a service can handle a large number of consumer interactions, attempting to maintain state in the business layer would consume considerable resources in order to maintain state for each unique consumer. This would restrict the number of requests that a service could handle at any one time.
  • Implement all business entities within a separate assembly. This assembly represents a shared component that can be used by both the business layer and the data access layer. Note, however, that business entities should not be exposed across a service boundary; instead use data transfer objects (DTOs) to transfer data between services.

For more information about implementing the business layer, see Chapter 7 "Business Layer Guidelines". For information about business entities, see Chapter 13 "Designing Business Entities."

Communication

When designing the communication strategy for your service application, the protocol you choose should be based on the deployment scenario for your service. Consider the following guidelines when designing a communication strategy:

  • If the service will be deployed within a closed network, you can use Transmission Control Protocol (TCP) for communication that is more efficient. If the service will be deployed on a public-facing network, you should choose Hypertext Transfer Protocol (HTTP).
  • Determine how to handle unreliable or intermittent communication reliably, perhaps by caching messages and sending them when a connection is available, and how to handle asynchronous calls. Decide if message communication must be one way or two way, and whether you need to use the Duplex, Request Response, and Request-Reply patterns.
  • Use dynamic URL behavior with configured endpoints for maximum flexibility, and determine how you will validate endpoint addresses in messages.
  • Choose appropriate communication protocols, and ensure that you protect data sent across communication channels using encryption and/or digital signatures.

For more information about communication protocols and techniques, see Chapter 18 "Communication and Messaging."

Data Layer

The data layer in a services application includes the data access functionality that interacts with external data sources. These data sources could be databases, other services, the file system, SharePoint lists, or any other applications that manage data. Data consistency is critical to the stability and integrity of your service implementation, and failure to validate the consistency of data received by the service can lead to invalid data inserted into the data store, unexpected exceptions, and security breaches. As a result, you should always include data consistency checks when implementing a service. Consider the following guidelines when designing your data layer:

  • The data layer should be deployed to the same tier as the business layer where possible. Deploying the data layer on a separate physical tier will require serialization of objects as they cross physical boundaries.
  • Always use abstraction when implementing an interface to the data layer. This is normally achieved by using the Data Access or Table Data Gateway patterns, which use well-known types for inputs and outputs.
  • For simple Create, Read, Update, and Delete (CRUD) operations, consider creating a class for each table or view in the database. This represents the Table Module pattern, where each table has a corresponding class with operations that interact with the table. Plan how you will handle transactions.
  • Avoid using impersonation or delegation to access the database. Instead, use a common entity to access the database, while providing user identity information so that log and audit processes can associate users with the actions they perform.

For more information about implementing the data layer, see Chapter 8 "Data Layer Guidelines."

Exception Management

Designing an effective exception-management strategy is important for the security and reliability of your service application. Failure to do so can leave your application vulnerable to Denial of Service (DoS) attacks, and may also allow it to reveal sensitive and critical information. Raising and handling exceptions is an expensive operation, so it is important that the design take into account the potential impact on performance. A good approach is to design a centralized exception management and logging mechanism, and to consider providing access points that support instrumentation and centralized monitoring in order to assist system administrators. Consider the following guidelines when designing an exception management strategy:

  • Ensure that you catch unhandled exceptions, and clean up resources after an exception occurs. Avoid exposing sensitive data in service exceptions, log files, and audit files.
  • Do not catch exceptions unless you can handle them; for example, to remove sensitive information or add additional information to the exception. Do not use exceptions to control application logic flow. Avoid the use of custom exceptions when not necessary.
  • Use SOAP Fault elements or custom extensions to return exception details to the caller.

For more information about designing an exception management strategy, see Chapter 17 "Crosscutting Concerns."

Message Construction

When data is exchanged between a service and a consumer, it must be wrapped inside a message. The format of that message is based on the types of operations you must support. For example, you might be exchanging documents, executing commands, or raising events. When using slow message delivery channels, you should also consider including expiration information in the message. Consider the following guidelines when designing a message construction strategy:

  • Determine the appropriate patterns for message construction (such as Command, Document, Event, and Request-Response).
  • Divide very large quantities of data into relatively small chunks, and send them in sequence.
  • Include expiration information in messages that are time sensitive. The service should ignore expired messages.

Message Endpoint

The message endpoint represents the connection that applications use to interact with your service. The implementation of your service interface provides the message endpoint. When designing the service implementation, you must consider the type of message that you are consuming. In addition, you should design for a range of scenarios related to handling messages. Consider the following guidelines when designing message endpoints:

  • Determine relevant patterns for message endpoints (such as Gateway, Mapper, Competing Consumers, and Message Dispatcher).
  • Design for disconnected scenarios. For example, you may need to support guaranteed delivery by caching or storing messages for later delivery. Ensure you do not attempt to subscribe to endpoints while disconnected.
  • Determine if you should accept all messages, or implement a filter to handle specific messages.
  • Design for idempotency in your service interface. Idempotency is the situation where you could receive duplicate messages from the same consumer, but should only handle one. In other words, an idempotent endpoint will guarantee that only one message will be handled, and that all duplicate messages will be ignored.
  • Design for commutativity. Commutativity is the situation where the messages could arrive out of order. In other words, a commutative endpoint will guarantee that messages arriving out of order will be stored and then processed in the correct order.

Message Protection

When transmitting sensitive data between a service and its consumer, you should design for message protection. You can use transport layer protection (such as IPSec or SSL) or message-based protection (such as encryption and digital signatures). Consider the following guidelines when designing message protection:

  • Use message-based security when you require end to end security and it is possible that intermediaries such as servers and routers will exist between the service and the caller. Message-based security helps to protect sensitive data in messages by encrypting it, and a digital signature will help to protect against repudiation and tampering of the messages. However, keep in mind that applying security will affect performance.
  • If interactions between the service and the consumer are not routed through intermediaries, such as other servers and routers, you can use transport layer security such as IPSec or SSL. However, if the message passes through one or more intermediaries, always use message-based security. With transport layer security, the message is decrypted and then encrypted at each intermediary through which it passes—which represents a security risk.
  • For maximum security, consider using both transport layer and message-based security in your design. Transport layer security will help to protect the headers information that cannot be encrypted using message based security.
  • When designing extranet or business-to-business services, consider using message-based brokered authentication with X.509 certificates. In the business-to-business scenario, the certificate should be issued by a commercial certificate authority. For extranet services, you can use certificates issued through an organization-based certificate service.

Message Transformation

When passing messages between a service and consumer, there are many cases where the message must be transformed into a format that the consumer can understand. This normally occurs in cases where consumers that cannot use messaging must process data retrieved from a message-based system. You can use adapters to provide access to the message channel for such consumers, and translators to convert the message data into a format that each consumer understands. Consider the following guidelines when designing for message transformation:

  • Determine if you must perform transformation; and, if so, identify relevant patterns for message transformation. For example, the Normalizer pattern can be used to translate semantically equivalent messages into a common format. Avoid using a canonical model when not necessary.
  • Ensure you perform transformations at the appropriate location to avoid repeated processing and unnecessary overheads.
  • Use metadata to define the message format, and consider using an external repository to store this metadata.
  • Consider using mechanisms such as BizTalk Server that can perform message transformations between a range of formats and client types.

Message Exchange Patterns

A Message Exchange Pattern defines a conversation between a service and the service consumer. This conversation represents a contract between the service and the consumer. The W3C standards group defines two patterns for SOAP messages: Request-Response and SOAP Response. Another standards group named OASIS has defined a Business Process Execution Language (BPEL) for services. BPEL defines a process for exchanging business process messages. In addition, other organizations have defined specific message exchange patterns for exchanging business process messages. Consider the following guidelines when designing message exchange patterns:

  • Choose patterns that match your requirements without adding unnecessary complexity. For example, avoid using a complex business process exchange pattern if the Request-Response pattern is sufficient. For one-way messages, consider the Fire and Forget pattern.
  • When using business process modeling techniques, be careful not to design exchange patterns based on process steps. Instead, the patterns should support operations that combine process steps.
  • Use existing standards for message exchange patterns instead of inventing your own. This promotes a standards-based interface that will be understood by many consumers. In other words, consumers will be more inclined to interact with standards-based contracts instead of having to discover and adapt to non-standard contracts.

Representational State Transfer

Representational State Transfer (REST) is an architectural style that is based on HTTP and works very much like a Web application. However, instead of a user interacting with and navigating through Web pages, applications interact with and navigate through REST resources using the same semantics as a Web application. In REST, a resource is identified by a Uniform Resource Identifier (URI), and the actions that can be performed against a resource are defined by using HTTP verbs such as GET, POST, PUT, and DELETE. Interaction with a REST service is accomplished by performing HTTP operations against a URI, which is typically in the form of an HTTP-based URL. The result of an operation provides a representation of the current state for that resource. In addition, the result can contain links to other resources that you can move to from the current resource.

The most common misconception about REST is that it is only useful for CRUD operations against a resource. REST can be used with any service that can be represented as a state machine. In other words, as long as you can break a service down into distinguishable states, such as retrieved and updated, you can convert those states into actions and demonstrate how each state can lead to one or more states. Consider how the UI of a Web application represents a state machine. When you access a page, the information displayed represents the current state of that information. You might have the ability to change that state by POSTing form fields, or by moving to another page using links that are included in the current page. A RESTful service works the same way, in that an application can perform a GET operation on a resource to get the current state of that resource, change the state of the resource by performing a PUT operation, or move to a different resource using links provided by the current resource.

Both application state and resource state exist in RESTful services. The client stores all application state, while the server stores only the resource state. Each individual request sent from the client to the server must contain all of the information necessary for the server to fully understand that request. In other words, the client must transfer any relevant application state in its request. The client can then make decisions on how to modify the resource state, based upon the server responses. Passing the application state each time allows the application design to scale, as you can now add multiple identical Web servers and load balance in such a way that the client needs no affinity to one particular server or any shared application state.

A REST style service has the qualities of safety and idempotency. Safety refers to the ability to repeat a request many times and get back the same answer without side effects. Idempotency refers to behavior where making a single call has the same consequences as making the same call several times. The presence of these qualities adds robustness and reliability because, even if HTTP is unreliable, you can safely reissue a request when the server is nonresponsive or returns a failure.

Consider the following guidelines when designing REST resources:

  • Consider using a state diagram to model and define resources that will be supported by your REST service. Do not use session state within a REST service.
  • Choose an approach for resource identification. A good practice would be to use meaningful names for REST starting points and unique identifiers, as part of their overall path, for specific resource instances. Avoid putting actions into the URI with QueryString values.
  • Decide if multiple representations should be supported for different resources. For example, decide if the resource should support an XML, Atom, or JavaScript Object Notation (JSON) format and make it part of the resource request. A resource could be exposed as both (for example) https://www.contoso.com/example.atom and https://www.contoso.com/example.json (note: links are to placeholder sites). Do not use QueryString values to define actions on a URI. Instead, all actions are based on the HTTP operation performed against a URI.
  • Do not overuse the POST operation. A good practice is to use specific HTTP operations such as PUT or DELETE as appropriate to reinforce the resource-based design and the use of a uniform interface.
  • Take advantage of the HTTP application protocol to use common Web infrastructure (caching, authentication, common data representation types, and so on).
  • Ensure that your GET requests are safe, meaning that they always return the same result when called. Consider making your PUT and DELETE requests idempotent, meaning that repeated identical requests should have the same effect as a single request.

Service Layer

The service layer contains components that define and implement services for your application. Specifically, this layer contains the service interface (which is composed of contracts), the service implementation, and translators that convert internal business entities to and from external data contracts. Consider the following guidelines when designing your service layer:

  • Do not implement business rules in the service layer. The service layer should only be responsible for managing service requests and for translating data contracts into entities for use by the business layer.
  • Access to the service layer should be defined by policies. Policies provide a way for consumers of the service to determine the connection and security requirements, as well as other details related to interacting with the service.
  • Use separate assemblies for major components in the service layer. For example, the interface, implementation, data contracts, service contracts, fault contracts, and translators should all be separated into their own assemblies.
  • Interaction with the business layer should only be through a well-known public interface. The service layer should never call the underlying business logic components.
  • The service layer should have knowledge of business entities used by the business layer. This is typically achieved by creating a separate assembly that contains business entities shared between the service layer and business layer.

SOAP

SOAP is a message-based protocol in which the message is composed of an XML envelope that contains a header and body. The header can provide information that is external to the operation performed by the service. For example, a header may contain security, transaction, or routing information. The body contains contracts, in the form of XML schemas, which define the service and the actions it can perform. Compared to REST, SOAP gives more protocol flexibility, and so you can utilize higher-performance protocols such as TCP. SOAP supports the WS-* standards including security, transactions, and reliability. Message security and reliability ensure that the messages not only reach their destination, but also that those messages have not been read or modified during transit. Transactions provide the ability to group operations and provide roll back ability in the case of a failure.

SOAP is useful when performing RPC-type interactions between services or decoupled layers of an application. It excels at providing an interface between new and legacy systems on an internal network. A service layer can be placed on top of an older system, allowing API-type interaction with the system without having to redesign the system to expose a REST resource model. SOAP is also useful where information is actively routed to one or more systems that may change communication protocols frequently over their lifetimes. It is also helpful when you want to encapsulate information or objects in an opaque manner and then store or relay that information to another system.

If you want your application to be scalable by using Web farms or load balancing, avoid storing session state on the server. Storing sessions on the server means that a particular server must service the client throughout the duration of the session or, in the case of load balancing, must pass the session information to another server. Passing session state between servers makes failover and scale out scenarios much harder to implement.

Consider the following guidelines when designing SOAP messages:

  • Within a SOAP envelope, the SOAP header is optional but the SOAP body is mandatory. Avoid the use of complex types in all message schemas.
  • Consider using SOAP faults for errors instead of relying on the default error handling behavior. When returning error information, the SOAP fault must be the only child element within the SOAP body.
  • To force processing of a SOAP header block, set the block's mustUnderstand attribute to “true” or “1”. Errors that occur when processing the SOAP header should be returned as a SOAP fault in the SOAP header element.
  • Research and utilize WS-* standards. These standards provide consistent rules and methods for dealing with the issues commonly encountered in a messaging architecture.

Validation

Designing an effective input validation and data validation strategy is critical to the security of your application. You must determine the validation rules for data you receive from consumers of the service. Consider the following guidelines when designing a validation strategy:

  • Validate all data received by the service interface, including data fields associated with the message, and return informative error messages if validation fails. Consider using XML schemas to validate incoming messages.
  • Check all input for dangerous or malicious content, and consider the way that data will be used. For example, if the data will be used to initiate database queries you must protect the database from SQL injection attacks. This may be through the use of stored procedures or parameterized queries to access the database.
  • Determine your signing, encryption, and encoding strategies.
  • Understand the trust boundaries between layers and elsewhere so that you can validate data that crosses these boundaries. However, determine if validation that occurs in other layers is sufficient. If data is already trusted, you might not need to validate it again.

For more information about validation techniques, see Chapter 17 "Crosscutting Concerns."

Technology Considerations

Take into account the following technology considerations when designing a service:

  • Consider using ASMX for simplicity, but only when a Web server running IIS is available.
  • Consider using WCF services if you require advanced features such as reliable sessions and transactions, activity tracing, message logging, performance counters, and support for multiple transport protocols.
  • If you are using ASP.NET Web services, and you require message-based security and binary data transfer, consider using Web Service Extensions (WSE).
  • If you decide to use WCF, consider the following:
    • If you want interoperability with non-WCF or non-Windows clients, consider using HTTP transport based on SOAP specifications.
    • If you want to support clients within an intranet, consider using the TCP protocol and binary message encoding with transport security and Windows authentication.
    • If you want to support WCF clients on the same machine, consider using the named pipes protocol and binary message encoding.
    • Consider defining service contracts that use an explicit message wrapper instead of an implicit one. This allows you to define message contracts as inputs and outputs for your operations, which then allows you to extend the data contracts included in the message contract without affecting the service contract.

Deployment Considerations

Services applications are usually designed using the layered approach, where the service interface, business, and data layers are decoupled from each other. You can use distributed deployment for a services application in exactly the same way as any other application type. Services may be deployed to a client, a single server, or multiple servers across an enterprise. However, when deploying a services application, you must consider the performance and security issues inherent in distributed scenarios, and take into account any limitations imposed by the production environment. Consider the following guidelines when deploying a services application:

  • Locate the service layer on the same tier as the business layer if possible to improve application performance.
  • When a service is located on the same physical tier as the consumer of the service, consider using named pipes or shared memory for communication.
  • If the service is accessed only by other applications within a local network, consider using TCP for communication.
  • Configure the service host to use transport layer security only if consumers have direct access to the service and requests do not pass through intermediaries.
  • Disable tracing and debug-mode compilation for all services except during development and testing.

For more information on deployment patterns and scenarios, see Chapter 19 "Physical Tiers and Deployment."

Relevant Design Patterns

Key patterns are organized into categories such as Communication, Data Consistency, Message Construction, Message Endpoint, Message Protection, Message Transformation, REST, Service Interface, and SOAP; as shown in the following table. Consider using these patterns when making design decisions for each category.

Category

Relevant patterns

Communication

Duplex. Two-way message communication where both the service and the client send messages to each other independently, irrespective of the use of the one-way or Request-Reply pattern.

Fire and Forget. A one-way message communication mechanism used when no response is expected.

Reliable Sessions. End to end reliable transfer of messages between a source and a destination, regardless of the number or type of intermediaries that separate the endpoints.

Request Response. A two-way message communication mechanism where the client expects to receive a response for every message sent.

Data Consistency

Atomic Transactions. Transactions that are scoped to a single service operation.

Cross-service Transactions. Transactions that can span multiple services.

Long-running transactions. Transactions that are part of a workflow process.

Message Construction

Command Message. A message structure used to support commands.

Document Message. A structure used to reliably transfer documents or a data structure between applications.

Event Message. A structure that provides reliable asynchronous event notification between applications.

Request-Reply. Use separate channels to send the request and the reply.

Message Endpoint

Competing Consumer. Set multiple consumers on a single message queue and have them compete for the right to process the messages, which allows the messaging client to process multiple messages concurrently.

Durable Subscriber. In a disconnected scenario, messages are saved and then made accessible to the client when it connects to the message channel in order to provide guaranteed delivery.

Idempotent Receiver. Ensure that a service will handle a message only once.

Message Dispatcher. A component that sends messages to multiple consumers.

Messaging Gateway. Encapsulate message-based calls into a single interface in order to separate it from the rest of the application code.

Messaging Mapper. Transform requests into business objects for incoming messages, and reverse the process to convert business objects into response messages.

Polling Consumer. A service consumer that checks the channel for messages at regular intervals.

Service Activator. A service that receives asynchronous requests and invokes operations in business components.

Selective Consumer. The service consumer uses filters to receive messages that match specific criteria.

Transactional Client. A client that can implement transactions when interacting with a service.

Message Protection

Data Confidentiality. Use message-based encryption to protect sensitive data in a message.

Data Integrity. Ensure that messages have not been tampered with in transit.

Data Origin Authentication. Validate the origin of a message as an advanced form of data integrity.

Exception Shielding. Prevent a service from exposing information about its internal implementation when an exception occurs.

Federation. An integrated view of information distributed across multiple services and consumers.

Replay Protection. Enforce message idempotency by preventing an attacker from intercepting a message and executing it multiple times.

Validation. Check the content and values in messages to protect a service from malformed or malicious content.

Message Transformation

Canonical Data Mapper. Use a common data format to perform translations between two disparate data formats.

Claim Check. Retrieve data from a persistent store when required.

Content Enricher. A component that enriches messages with missing information obtained from an external data source.

Content Filter. Remove sensitive data from a message and reduce network traffic by removing unnecessary data from a message.

Envelope Wrapper. A wrapper for messages that contains header information used, for example, to protect, route, or authenticate a message.

Normalizer. Convert or transform data into a common interchange format when organizations use different formats.

REST

Behavior. Applies to resources that carry out operations. These resources generally contain no state of their own, and only support the POST operation.

Container. Builds on the entity pattern by providing the means to dynamically add and/or update nested resources.

Entity. Resources that can be read with a GET operation, but can only be changed by PUT and DELETE operations.

Store. Allows entries to be created and updated with the PUT operation.

Transaction. Resources that support transactional operations.

Service Interface

Façade. Implement a unified interface for a set of operations in order to provide a simplified interface and reduce coupling between systems.

Remote Façade. Create a high level unified interface to a set of operations or processes in a remote subsystem to make that subsystem easier to use, by providing a course-grained interface over fine-grained operations to minimize calls across the network.

Service Interface. A programmatic interface that other systems can use to interact with the service.

SOAP

Data Contract. A schema that defines data structures passed with a service request.

Fault Contract. A schema that defines errors or faults that can be returned from a service request.

Service Contract. A schema that defines operations that the service can perform.

For more information on the Duplex and Request Response patterns, see "Designing Service Contracts" at https://msdn.microsoft.com/en-us/library/ms733070.aspx.

For more information on the Request-Reply pattern, see "Request-Reply" at http://www.eaipatterns.com/RequestReply.html.

For more information on the Atomic and Cross-service Transaction patterns, see "WS-* Specifications" at http://docs.oasis-open.org/ws-tx/wsat/2006/06.

For more information on the Command, Document Message, Event Message, Durable Subscriber, Idempotent Receiver, Polling Consumer, and Transactional Client patterns, see "Messaging Patterns in Service-Oriented Architecture, Part I" at https://msdn.microsoft.com/en-us/library/aa480027.aspx.

For more information on the Data Confidentiality and Data Origin Authentication patterns, see "Chapter 2: Message Protection Patterns" at https://msdn.microsoft.com/en-us/library/aa480573.aspx.

For more information on the Replay Detection, Exception Shielding, and Validation patterns, see "Chapter 5: Service Boundary Protection Patterns" at https://msdn.microsoft.com/en-us/library/aa480597.aspx.

For more information on the Claim Check, Content Enricher, Content Filter, and Envelope Wrapper patterns, see "Messaging Patterns in Service Oriented Architecture, Part 2" at https://msdn.microsoft.com/en-us/library/aa480061.aspx.

For more information on the Remote Façade pattern, see "P of EAA: Remote Façade" at http://martinfowler.com/eaaCatalog/remoteFacade.html.

For more information on REST patterns such as Behavior, Container, and Entity, see "REST Patterns" at http://developer.mindtouch.com/REST/REST_Patterns.

Additional Resources

For more information, see the following resources: