J.D. Meier, Alex Homer, David Hill, Jason Taylor, Prashant Bansode, Lonnie Wall, Rob Boucher Jr, Akshay Bogawat
- Understand the nature and use of services.
- Learn the general guidelines for different service scenarios.
- Learn the guidelines for the key attributes of services.
- Learn the guidelines for the layers within a services application.
- Learn the guidelines for performance, security, and deployment.
- Learn the key patterns and technology considerations related to services.
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 within other services to provide more complex functionality. Services are distributable and can be accessed from a remote machine as well as from the local 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 common services application architecture. Figure 1 Common services application architecture
Common Services Scenarios
Services are flexible by nature and can be used in a wide variety of scenarios and combinations. The following are key typical scenarios:
- Service exposed over the Internet.** This scenario describes a service that is consumed over the Internet. Decisions on authentication and authorization must be based on Internet trust boundaries and credentials options. For example, username authentication is more likely in the Internet scenario than the intranet scenario. This scenario includes business-to-business (B2B) as well as consumer-focused services. A Web site that allows you to schedule visits to your family doctor would be an example of this scenario.
- Service exposed over an intranet. This scenario describes a service that is consumed over an intranet. Decisions on authentication and authorization must be based on intranet trust boundaries and credentials options. For example, the Microsoft® Active Directory® directory service is more likely to be the chosen user store in the intranet scenario than in the Internet scenario. An enterprise Web-mail application would be an example of this 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) application that is consumed internally by a thick client application and over the Internet by a Web application would be an example of this scenario.
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 invalid request orders. 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 (ODS) that provides a service-based interface.
- Design coarse-grained operations. Avoid chatty calls to the service interface, which can lead to very poor performance. Instead, use the Façade pattern to package smaller fine-grained operations into single coarse-grained operations.
- Design entities for extensibility. Data contracts should be designed so that you can extend them without affecting consumers of the service.
- Compose entities from standard elements. When possible, compose the complex types used by your service from standard elements.
- Design without the assumption that you know who the client is. You should not make assumptions about the client, and how they plan to use the service you provide.
- Design only for the service contract. Do not implement functionality that is not reflected by the service contract. In addition, the implementation of a service should never be exposed to external consumers.
- Design to assume the possibility of invalid requests. Never assume that all messages received by the service are valid.
- Separate functional business concerns from infrastructure operational concerns. Cross-cutting logic should never be combined with application logic. Doing so can lead to implementations that are difficult to extend and maintain.
- Ensure that the service can detect and manage repeated messages (idempotency). When designing the service, implement well-known patterns, or take advantage of infrastructure services, to ensure that duplicate messages are not processed.
- Ensure that the service can manage messages arriving out of order (commutativity). If there is a possibility that messages might arrive out of order, implement a design that will store messages and then process them in the correct order.
SOA Services Considerations
- Design services to be application-scoped and not component-scoped. Service operations should be coarse-grained and focused on application operations. For example, with demographics data, you should provide an operation that returns all of the data in one call. You should not use multiple operations to return subsets of the data with multiple calls.**
- Decouple the interface from the implementation. In an SOA application, it is very important to keep internal business entities hidden from external clients. In other words, you should never define a service interface that exposes internal business entities. Instead, the service interface should be based on a contract with which external consumers interact. Inside the service implementation, you translate between internal business entities and external contracts.
- Design services 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.
- Design services to be autonomous. Services should not require anything from consumers of the service, and should not assume who the consumer is. In addition, you should design services with the assumption that malformed requests will be sent to it.
- Design compatibility based on policy. The service should publish a policy that describes how consumers can interact with the service. This is more important for public services, where consumers can examine the policy to determine interaction requirements.
Data Services Considerations
- Avoid using 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.
- Do not implement business rules with data services. Different consumers of the data will have unique viewpoints and rules. Attempting to implement rules in data access services will impose restrictions on the use of that data.
Workflow Services Considerations
- 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.
- Design a service that is dedicated to supporting workflow. Instead of adding workflow services to an existing service application, consider designing an autonomous service that supports only workflow requirements.
Services Application Frame
The following table lists the key areas to consider as you develop services architecture. Use the key issues in the table to understand where mistakes are most often made. The sections following this table provide guidelines for each of these areas.
|Area ||Key issues|
|Authentication and Authorization ||Lack of authentication across trust boundaries |
| ||Lack of authorization across trust boundaries |
| ||Granular or improper authorization |
|Communication ||Incorrect choice of transport protocol |
| ||Chatty communication with the service |
| ||Failing to protect sensitive data |
|Data Consistency ||Failing to check data for consistency |
| ||Improper handling of transactions in a disconnected model |
|Exception Management ||Using exceptions to control application flow |
| ||Not logging exceptions |
| ||Compromising message integrity when an exception occurs |
| ||Revealing sensitive information in the exception |
| ||Failing to implement a strategy for unhandled exceptions |
|Message Construction ||Not appreciating that message contents may be time-sensitive |
| ||Incorrect message construction for the operation |
| ||Passing too much data in a single message |
|Message Endpoint ||Not supporting idempotent operations |
| ||Implementing filters to handle specific messages |
| ||Subscribing to an endpoint while disconnected |
|Message Protection ||Not protecting sensitive data |
| ||Using transport layer protection for messages that cross multiple servers |
| ||Not considering data integrity |
|Message Transformation ||Unnecessary use of transformations |
| ||Implementing transformations at the wrong location |
| ||Using a canonical model when not necessary |
|Message Exchange Patterns ||Using complex patterns when not necessary |
| ||Using the Request/Response pattern for one-way messages |
|REST ||Overuse of POST operations against resources |
| ||Putting actions into the URI with QueryString values |
| ||Using session state within a Representational State Transfer (REST) service |
|SOAP ||Not choosing the appropriate security model |
| ||Not planning for fault conditions |
| ||Using complex types in the message schema |
|Validation ||Not validating message structures sent to the service |
| ||Failing to validate data fields associated with the message |
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 or a console application, you must use message-based authentication.
Consider the following guidelines when designing an authentication strategy:
- Identify a suitable mechanism for securely authenticating users.
- 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.
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.
- 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.
- Execute services under the most restrictive account that is appropriate.
Designing for data consistency is critical to the stability and integrity of your service implementation. Failure to validate the consistency of data received by the service can lead to invalid data being 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 for data consistency:
- Validate all parameters passed to the service components.
- Check input for dangerous or malicious content.
- Determine your signing, encryption, and encoding strategies.
- Use an XML schema to validate incoming SOAP messages.
When designing the communication strategy for your service application, the protocol you choose should be based on the deployment scenario your service must support. If the service will be deployed within a closed network, you can use Transmission Control Protocol (TCP) for more efficient communication. If the service will be deployed in to a public-facing network, you should choose the Hypertext Transfer Protocol (HTTP).
Consider the following guidelines when designing a communication strategy:
- Determine how to reliably handle unreliable or intermittent communication.
- Use dynamic URL behavior with configured endpoints for maximum flexibility.
- Validate endpoint addresses in messages.
- Determine how to handle asynchronous calls.
- Decide if message communication must be one-way or two-way.
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:
- Do not use exceptions to control business logic.
- Design a strategy for handling unhandled exceptions.
- Do not reveal sensitive information in exception messages or log files.
- Use SOAP Fault elements or custom extensions to return exception details to the caller.
- Disable tracing and debug-mode compilation for all services except during development and testing.
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 need to 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 constructions (such as Command, Document, Event, and Request-Reply).
- 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.
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).
- 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.
- Design for disconnected scenarios. For instance, you might need to support guaranteed delivery.
When transmitting sensitive data between a service and its consumer, you should design for message protection. You can use transport layer protection or message-based protection. However, in most cases, you should use message-based protection. For example, you should encrypt sensitive sections within messages and use a digital signature to protect the message from tampering.
Consider the following guidelines when designing message protection:
- If your messages will not be routed intermediary servers, consider using transport layer security such as SSL.
- If the message passes through one or more intermediary servers, use message-based protection, since with transport security alone the message will be decrypted and re-encrypted at each server it passes through.
- Use encryption to protect sensitive data in messages.
- Consider using digital signatures to protect messages and parameters from tampering.
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 non–message-based consumers need to process data from a message-based system. You can use adapters to provide access to the message channel for a non–message-based consumer, and translators to convert the message data into a format that the consumer understands.
Consider the following guidelines when designing for message transformation:
- Determine relevant patterns for message transformation. For example, the Normalizer pattern can be used to translate semantically equivalent messages into a common format.
- Use metadata to define the message format.
- Consider using an external repository to store the metadata.
Message Exchange Patterns
A Message Exchange Pattern (MEP) 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.
- 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 nonstandard contracts.
Representational State Transfer (REST)
Representational State Transfer (REST) is an architecture 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 Create, Read, Update, and Delete (CRUD) operations against a resource. However, 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 user interface (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. As such, the client must transfer any relevant application state in its request. The client can then make decisions on how to modify the resource state dependent on 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 idempotence. Safety refers to the ability to repeat a request many times and get back the same answer without side effects. Idempotent refers to behavior where making a single call has the same consequences as making the same call a series of 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 non-responsive 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.
- 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.
- Decide if multiple representations should be supported for different resources. For example, decide if the resource should support an XML, Atom, or JSON format and make it part of the resource request. A resource could be exposed as both http://www.microsoft.com/example.atom and http://www.microsoft.com/example.json .
- Do not use QueryString variables 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, ETags, authentication, and common data representation types, etc.).
- 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.
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, so you can utilize higher-performance protocols such as Transmission Control Protocol (TCP). SOAP supports 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 rollback 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 scale through the use of 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 through the duration of the session or must pass the session information to another server in the case of load balancing. 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, while the SOAP body is mandatory.
- Consider using SOAP faults for errors instead of relying on default error-handling.
- When returning error information, the SOAP fault can be the only child element within a SOAP body.
- Errors that occur when processing the SOAP header should be returned as a SOAP fault in the SOAP header element.
- In order to force processing of a SOAP header block, set the block’s mustUnderstand attribute to “true” or “1”.
- Research and utilize WS-* standards. These standards provide consistent rules and methods for dealing with the issues commonly encountered in a messaging architecture.
Designing an effective input-validation and data-validation strategy is critical to the security of your application. Determine the validation rules for data you receive from consumers of the service. Understand your trust boundaries so that you can validate any data that crosses these boundaries.
Consider the following guidelines when designing a validation strategy:
- Validate all data received by the service interface.
- Consider the way that data will be used. For example, if the data will be used in database queries, you must protect the database from SQL injection attacks.
- Understand your trust boundaries so that you can validate data that crosses these boundaries.
- Determine if validation that occurs in other layers is sufficient. If data is already trusted, you might not need to validate it again.
- Return informative error messages if validation fails.
Service Layer Considerations
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 that are shared between the service layer and business layer.
Business Layer Considerations
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 you 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.
- 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.
Data Layer Considerations
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, Microsoft Office SharePoint® lists, or any other applications that manage data.
Consider the following guidelines when designing your data layer:
- The data layer should be deployed to the same tier as the business layer. Deploying the data layer on a separate physical tier will require serialization of objects as they cross physical boundaries.
- Always use abstraction when providing an interface to the data access layer. This is normally achieved by using the Data Access or Table Data Gateway pattern, which use well-known types for inputs and outputs.
- For simple 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.
- Avoid using impersonation or delegation to access the data layer. Instead, use a common entity to access the data access layer, while providing user identity information so that log and audit processes can associate users with the actions they perform.
When designing the service interface, use operations that are as coarse-grained as possible. The level of granularity will depend on the type of service you are designing. For example, you would define an operation that returns all of the demographic data for a person in one call, rather than returning portions of the demographic data across multiple calls. Think of a service as an application that provides operations that are used to support business processes. Avoid creating a web of dependencies between services and service consumers, and the chatty communications that would result from a component-based design.
Consider the following guidelines when designing for maximum performance:
- Keep service contract operations as coarse-grained as possible.
- Do not mix business logic with translator logic. The service implementation is responsible for translations, and you should never include business logic in the translation process. The goal is to minimize complexity and improve performance by designing translators that are only responsible for translating data from one format to another.
Security encompasses a range of factors and is vital in all types of applications. Services applications must be designed and implemented to maximize security and, where they expose business functions, must play their part in protecting and securing the business rules, data, and functionality. Security issues involve a range of concerns, including protecting sensitive data, user authentication and authorization, guarding against attack from malicious code and users, and auditing and logging events and user activity. However, one specific area of concern for services is protecting messages in transit over the network.
Consider the following guidelines when designing a security strategy:
- When using message-based authentication, you must protect the credentials contained in the message. This can be accomplished by using encryption, or encryption combined with digital signatures.
- You can use transport layer security such as SSL. However, if your service passes through other servers, consider implementing message-based security. This is required because each time a message secured with transport layer security passes through another server, that server decrypts the message and then re-encrypts it before sending it on to the next server.
- When designing extranet or business-to-business (B2B) services, consider using message-based brokered authentication with X.509 certificates. In the B2B 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.
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 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 without passing through other servers or services.
|Category ||Relevant patterns|
|Communication ||Duplex |
| ||Fire and Forget |
| ||Reliable Sessions |
| ||Request Response |
|Data Consistency ||Atomic Transactions |
| ||Cross |
| ||Long |
|Message Construction ||Command Message |
| ||Document Message |
| ||Event Message |
|Message Endpoint ||Competing Consumer |
| ||Durable Subscriber |
| ||Idempotent Receiver |
| ||Message Dispatcher |
| ||Messaging Gateway |
| ||Messaging Mapper |
| ||Polling Consumer |
| ||Selective Consumer |
| ||Service Activator |
| ||Transactional Client |
|Message Protection ||Data Confidentiality |
| ||Data Integrity |
| ||Data Origin Authentication |
| ||Exception Shielding |
| ||Federation |
| ||Replay Protection |
| ||Validation |
|Message Transformation ||Canonical Data Mapper |
| ||Claim Check |
| ||Content Enricher |
| ||Content Filter |
| ||Envelope Wrapper |
| ||Normalizer |
|REST ||Behavior |
| ||Container |
| ||Entity |
| ||Store |
| ||Transaction |
|Service Interface ||Remote Façade |
|SOAP ||Data Contract |
| ||Fault Contract |
| ||Service Contract |
- Atomic Transactions.** Transactions that are scoped to a single service operation.
- Behavior (REST). Applies to resources that carry out operations. These resources generally contain no state of their own, and only support the POST operation.
- 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.
- Command Message.** A message structure used to support commands.
- 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.
- Container.** Builds on the entity pattern by providing the means to dynamically add and/or update nested resources.
- 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.
- Cross-service Transactions.** Transactions that can span multiple services.
- Data Confidentiality.** Use message-based encryption to protect sensitive data in a message.
- Data Contract.** A schema that defines data structures passed with a service request.
- 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.
- Document Message.** A structure used to reliably transfer documents or a data structure between applications.
- 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.
- Durable Subscriber.** In a disconnected scenario, messages are saved and then made accessible to the client when connecting to the message channel to provide guaranteed delivery.
- Entity (REST). Resources that can be read with a GET operation, but can only be changed by PUT and DELETE operations.
- Envelope Wrapper.** A wrapper for messages that contains header information used, for example, to protect, route, or authenticate a message.
- Event Message.** A structure that provides reliable asynchronous event notification between applications.
- Exception Shielding.** Prevent a service from exposing information about its internal implementation when an exception occurs.
- Façade. Implement a unified interface to a set of operations to provide a simplified reduced coupling between systems.
- Fault Contracts.** A schema that defines errors or faults that can be returned from a service request.
- Federation.** An integrated view of information distributed across multiple services and consumers.
- Fire and Forget.** A one-way message communication mechanism used when no response is expected.
- Idempotent Receiver.** Ensure that a service will only handle a message once.
- Long-running transactions.** Transactions that are part of a workflow process.
- 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.
- Normalizer.** Convert or transform data into a common interchange format when organizations use different formats.
- Polling Consumer.** A service consumer that checks the channel for messages at regular intervals.
- 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 endpoints.
- 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.
- Replay Protection.** Enforce message idempotency by preventing an attacker from intercepting a message and executing it multiple times.
- Request Response.** A two-way message communication mechanism where the client expects to receive a response for every message sent.
- Selective Consumer.** The service consumer uses filters to receive messages that match specific criteria.
- Service Activator.** A service that receives asynchronous requests to invoke operations in business components.
- Service Contract. A schema that defines operations that the service can perform.
- Service Interface. A programmatic interface that other systems can use to interact with the service.
- Store (REST). Allows entries to be created and updated with the PUT operation.
- Transaction (REST). Resources that support transactional operations.
- Transactional Client.** A client that can implement transactions when interacting with a service.
- Validation.** Check the content and values in messages to protect a service from malformed or malicious content.
The following technical considerations should be considered when designing a service layer:
- Consider using ASP.NET Web services (ASMX) for simplicity, but only when a suitable Web server will be available.
- Consider using Windows Communication Foundation (WCF) services for maximum feature availability and interoperability.
- 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 are using WCF and you want interoperability with non-WCF or non–Microsoft Windows® clients, consider using HTTP transport based on SOAP specifications.
- If you are using WCF and 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 are using WCF and you want to support WCF clients on the same machine, consider using the named pipes protocol and binary message encoding.
- If you are using WCF, 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.