Note that the information on this page is the BETA 1 of a guide that is now released. See
http://www.codeplex.com/AppArchGuide for the latest PDF and HTML content.
Chapter 11 - Communication Guidelines
- J.D. Meier, Alex Homer, David Hill,
Prashant Bansode, Lonnie Wall, Rob Boucher Jr, Akshay Bogawat
- Learn about the design impact of choosing a communication technology.
- Learn about the main issues related to each communication technology choice.
- Learn how to choose a communication technology for your scenario and application type.
This set of guidelines covers the important aspects you should consider when choosing a communication technology. The guidelines are organized by category; first, general communication design guidelines, and then specific guidelines for different areas of communication
design. These guideline categories represent the key areas where mistakes are most often made.
When designing communications for your application, consider the following guidelines:
- Consider communication strategies when crossing boundaries. Understand each of your boundaries and how they will impact communication. For example, the application domain (AppDomain), computer process, machine, and unmanaged code all represent boundaries
that that can be crossed when communicating with components of the application or external services and applications.
- Consider using unmanaged code for communication across AppDomain boundaries. Use unmanaged code to communicate across AppDomains boundaries. This approach requires assemblies that have full trust in order to interact with unmanaged code.
- Consider using message-based communication when crossing process boundaries. Use Windows Communication Foundation (WCF) with either the TCP or named pipes protocols to package data into a single call that can be serialized across process boundaries.
- Always use message-based communication when crossing physical boundaries. Use Windows Communication Foundation (WCF) or Microsoft Message Queuing (MSMQ) to communicate with remote machines across physical boundaries. Message-based communication
supports coarse-grained operations that reduce round trips when communicating across a network.
- Reduce round trips when accessing remote layers. When communicating with remote layers, reduce communication requirements by using coarse-grained message-based communication methods and use asynchronous communication if possible to avoid blocking
or freezing the user interface.
- Consider the serialization capabilities of the data formats being passed across boundaries. If you need to maintain data structure and names, consider XML serialization. Keep in mind that XML serialization imposes increased overhead. If performance
is critical, consider binary serialization because it is faster and the resulting serialized data is smaller than the XML equivalent.
- Consider hotspots while designing your communication policy. Hotspots include asynchronous and synchronous communication, data format, communication protocol, security, performance, and interoperability.
Message-based communication is a good choice for the following scenarios:
- If you are implementing a business system that represents a medium- to long-term investment; for example, when building a service that will be exposed to and used by partners for a long period of time.
- If you are implementing large scale systems with high availability characteristics.
- If you are building a service that you want to isolate from other services it uses, and from services that consumes it.
- If you expect communication at either of the endpoints to be sporadically unavailable, as in the case of wireless networks or applications that can be used offline.
- If you are dealing with real-world business processes that are modeled asynchronously. This will provide a cleaner mapping between your requirements and the behavior of the application.
When using message-based communication, consider the following guidelines:
- Consider that a connection will not always be present, and messages may need to be stored and then sent when a connection becomes available.
- Consider how to handle the case when a message response is not received. To manage the conversation state, your business logic can log the sent messages for later processing in case a response is not received.
- Consider implementing a correlation mechanism to identify the pair of messages sent and received. This correlation can be implemented in the messaging transport or in the business data.
- Consider implementing correlation in the business data to implement idempotency for business processes.
- Use a timeout value to determine the point at which receipt of a delayed response is no longer valid.
- Consider how to manage multiple message exchanges in long-running transactions.
- Use acknowledgements to force the correct sequencing of messages.
- If message response timing is critical for your communication, consider a synchronous programming model in which your client waits for each response message.
- Choose the appropriate communication technology depending on the combination of an endpoint (for example, IIS), a protocol (for example, HTTP), and a format (for example, SOAP).
- If no default channel meets your requirements, consider implementing custom channels by defining your own combination of endpoint, protocol, and format.
Coupling and Cohesion
Communication methods that impose interdependencies between the distributed parts of the application will result in a tightly-coupled application. A loosely-coupled application uses methods that impose a minimum set of requirements for communication to occur.
When designing for coupling and cohesion, consider the following guidelines:
- For loose coupling, choose a message-based technology such as ASMX or WCF.
- For loose coupling, consider using self-describing data and ubiquitous protocols such as HTTP and SOAP.
- To maintain cohesion, ensure that services and interfaces contain only methods that are closely related in purpose and functional area.
Asynchronous and Synchronous Communication
Consider the following guidelines when deciding whether to use synchronous or asynchronous communication:
- For maximum performance, loose-coupling, and minimized system overhead, consider using an asynchronous communication model.
- Where you must guarantee the order in which operations take place, or you use operations that depend on the outcome of previous operations, consider a synchronous model.
- For asynchronous local in-process calls, use the platform features (such as Begin and End versions of methods and callbacks) to implement asynchronous method calls.
- Implement asynchronous interfaces as close as possible to the caller to obtain maximum benefit.
- If some recipients can only accept synchronous calls, and you need to support synchronous communication, consider wrapping existing asynchronous calls in a component that performs synchronous communication.
Consider the following options for asynchronous store-and-forward message delivery:
- Consider using local caches to store messages for later delivery in case of system or network interruption.
- Consider using Message Queuing to queue messages for later delivery in case of system or network interruption or failure. Message Queuing can perform transacted message delivery and supports reliable once-only delivery.
- Consider using BizTalk Server to interoperate with other systems and platforms at enterprise level, or for Electronic Data Interchange (EDI).
Passing Data Through Tiers - Data Formats
To support a diverse range of business processes and applications, consider the following guidelines when selecting a data format for a communication channel:
- You can pass data in several different formats: as a series of scalar values, as an XML string, as a DataSet, or as a custom object (such as a business entity component).
- You can return data in several different formats: as output-parameter scalar values, as an XML string, as a DataSet, as a DataReader, or as a custom object (such as a business entity component).
- For any type of data, consider using custom objects; these can impose a lower overhead than DataSets and support both binary and XML serialization.
- If your application works mainly with sets of data, and needs functionality such as sorting, searching and data binding, consider using DataSets.
- If your application works mainly with instance data, consider using scalar values for better performance.
Data Format Considerations
||You need loose coupling, where the caller must know about only the data that defines the business entity, and not a specific type or the specific structure of the business entity.
||You want built-in support for serialization.
||You can handle the likelihood of schema changes. Scalar values produce tight coupling, which will require method signatures to be modified, impacting the calling code.
||You need loose coupling, where the caller must know about only the data that defines the business entity and the schema that provides metadata for the business entity.
||You need to support different types of callers, including third-party clients.
||You need built-in support for serialization.
||You need support for complex data structures.
||You need to handle sets and complex relationships.
||You need to track changes to data within the DataSet.
||You need support for complex data structures.
||You are communicating with components that know about the object type.
||You want to support binary serialization for performance.
The format you choose for messages, and the communication synchronicity, affect the ability of participants to exchange data, the integrity of that data, and the performance of the communication channel.
Consider the following guidelines when choosing a message format and handling messages:
- Decide if the message format and encoding combination will limit the clients that can participate. For example, a firewall may block specific ports and prevent TCP protocol communication.
- Ensure that type information is not lost during the communication process. Binary serialization preserves type fidelity, which is useful when passing objects between client and server. Default XML serialization serializes only public properties and fields
and does not preserve type fidelity.
- Ensure that your application code can detect and manage messages that arrive more than once (idempotency).
- Ensure that your application code can detect and manage multiple messages that arrive out of order (commutativity).
<<Needs to use the If X, Consider Y pattern>>
Consider the following guidelines for the impact of different data types on communication performance:
- If you are communicating between endpoints within the same network, consider using binary encoding with the TCP protocol for maximum performance. However, binary encoding using the HTTP protocol is also possible by using a binary formatter.
- If you are communicating between endpoints on the same machine, consider using binary encoding with named pipes for maximum performance.
- If you want to implement efficient serialization, consider using custom classes.
- If you need interoperability and the flexibility to communicate with different systems, consider using XML. However, XML is verbose and may require considerable parsing effort. Applications that use XML may pass large amounts of data over the network.
- If you need to cache data between requests, consider using a DataSet. However, DataSet objects are expensive to create and serialize.
- If you want to allow clients to access fields by name and avoid the late binding associated with field collection lookups, consider using a Typed DataSet.
The design of your communication interfaces will also have a considerable impact on performance. When designing communication interfaces, consider the following guidelines:
- Avoid property-based interfaces.
- Avoid fine-grained "chatty" interfaces for cross-process and cross-machine communication. These require the client to make multiple method calls to perform a single logical unit of work. Consider using the Façade pattern to provide a coarse-grained
wrapper for existing chatty interfaces to encapsulate and coordinate the functionality of one or more objects and/or methods.
- Reduce network roundtrips by passing data as a single unit, as described by the Data Transfer Object pattern, instead of passing individual data types one at a time.
- Reduce the volume of data sent to remote methods where possible. This reduces serialization overhead and network latency.
The data format you use for passing data across tiers can have significant performance impact:
- Consider using custom classes, for passing data across tiers as it provide efficient serialization.
- When using XML for passing data across tiers, XML is verbose and can require considerable parsing effort. Consider using XML only when you need to pass large amounts of data over the network.
- Avoid passing DataReader objects between layers because they require an open connection.
- Be deliberate when using Datasets for passing the data across tiers, as they can be cached across requests. But beware DataSet objects are expensive to create and serialize.
- When using datasets to pass data across tiers, consider using Typed DataSet objects, which permit clients to access fields by name and to avoid the collection lookup overhead.
One of the most vital issues when designing communication systems is protecting sensitive information that passes over the communication channels. In addition, you must consider implementing mechanisms that ensure the integrity of communication and messages,
and detect tampering. There are two fundamental areas of concern for securing communications: transport security and message security.
Transport security is used to provide point-to-point security between the two endpoints. Protecting the channel prevents attackers from accessing all messages on the channel. Common approaches to transport security are Secure Sockets Layer (SSL) and IPSec.
Consider the following when deciding to use transport security:
- When using transport security, the transport layer passes the user credentials and claims to the recipient. This means that the user credentials are transport-dependent.
- Transport security provides good interoperability. Communicating parties do not need to understand the WS-Security specifications.
- Transport security supports a limited set of credentials and claims compared to message security.
- If interactions between the service and the consumer are not routed through other services, you can use just transport layer security.
- If the message passes through one or more servers, always use message-based protection as well as transport layer security. With transport layer security, the message is decrypted and then encrypted at each server it passes through; which represents a security
Message security can be used with any transport protocol. You should protect the content of individual messages passing over the channel whenever they pass outside your own secure network, and even within your network for highly sensitive content. Common approaches
to message security are encryption and digital signatures.
Consider the following when deciding to use message security:
- User credentials and claims are encapsulated in every message by using the WS-Security specifications for securing messages. This means that it is largely independent of the transport protocol.
- Message Security does not support interoperability with older ASMX clients because it requires both the client and the service to support WS-Security specifications.
Consider the following guidelines for communication security:
- Always implement transfer security for sensitive messages that pass out of your secure network.
- Always use message security where there are intermediate systems between the client and the service. Intermediate servers will receive the message, handle it, then create a new SSL or IPSec connection, and can therefore access the unprotected message.
- Combine transport and message security techniques for maximum protection.
- If you need to encrypt your calls or authenticate your client, you must use an HTTP-based application hosted in IIS. No default security is provided when hosted outside IIS.Ensure that you validate all received messages to protect systems. You can use XML
Schemas to validate XML-based messages and XML message content.
It may be necessary for the communicating parties in an application to maintain state across multiple requests.
When deciding how to implement state management, consider the following guidelines:
- Decide if it is necessary to maintain state between calls. Maintaining state will consume resources.
- If you are using a state-full programming model within a component or service, you can use your database to store state information.
- ASMX services have access to the Application Context class, which provides access to the default application scope and session scope state stores.
- WCF provides extensible objects that can be used for state management.
The main factors that influence interoperability of applications and components are the availability of suitable communication channels, plus the formats and protocols that the participants can understand. Consider the following guidelines for maximizing interoperability:
- To enable communication with wide variety of platforms and devices, consider using standard protocols such as SOAP. The structure of the message is defined using XML schema.
- Consider the impact of protocol decisions. For example, target systems may be protected with firewalls that block some protocols.
- Consider the impact of data format decisions. For example, target systems may not understand platform-specific types such as DataSets, or may have different ways of handling and serializing types.
- Consider the impact of security decisions. For example, some message encryption/decryption techniques may not be available on all systems.
Choosing a Communication Technology
When choosing a communication technology, consider the following factors:
- Interoperability – Consider using standard protocols such as SOAP to enable communication with a wide variety of platforms and devices. The structure of the message is defined using an XML Schema.
- Tight Coupling – A tightly-coupled application uses communication methods that impose interdependencies between the distributed parts of the application.
- Loose Coupling – A loosely-coupled application uses methods that impose a minimum set of requirements for communication to occur. Consider using self-describing data and ubiquitous protocols such as HTTP and XML for loose coupling.
- Message format – Decide if the message format and encoding combination will limit the clients that can participate. If both the client and server are .NET applications, you can use a binary protocol.
- Type Information – Make sure that type information is not lost during the communication process. Binary serialization preserves type fidelity, which is useful when passing objects between client and server.
- Serialization – For the two main types of serialization, XML and binary, only public properties and fields are serialized.
- State Management – Decide if it is necessary to maintain state between calls. Maintaining state will consume resources. If you are using a stateless programming model, SQL server can be used to store state information.
- Security – If you need to encrypt your calls or authenticate your client, you must use an HTTP-based application hosted in IIS. No default security is provided when hosted outside IIS.
- Performance – Binary encoding with the TCP or named pipes protocols can provide better inter-process communication performance.
- Scalability – Hosting your application inside IIS will improve scalability.
WCF Technology Options
The following guidelines will help you to understand how you can use WCF:
- You can use WCF to communicate with Web services to achieve interoperability with other platforms that also support SOAP, such as the J2EE-based application servers.
- You can use WCF to communicate with Web services using messages not based on SOAP for applications with formats such as RSS.
- You can use WCF to communicate using SOAP messages and binary encoding for data structures when both the server and the client use WCF.
- You can use WS-MetadataExchange in SOAP requests to obtain descriptive information about a service, such as its WSDL definition and policies.
- You can use WS-Security to implement authentication, data integrity, data privacy, and other security features.
- You can use WS-Reliable Messaging to implement reliable end-to-end communication, even when one or more Web services intermediaries must be traversed.
- You can use WS-Coordination to coordinate two-phase commit transactions in the context of Web services conversations.
- You can use WCF to build REST Singleton & Collection Services, ATOM Feed and Publishing Protocol Services, and HTTP Plain XML Services.
WCF supports several different protocols for communication:
- When providing public interfaces that are accessed from the Internet, use the HTTP protocol.
- When providing interfaces that are accessed from within a private network, use the TCP protocol.
- When providing interfaces that are accessed from the same machine, use the named pipes protocol, which supports a shared buffer or streams for passing data.
ASMX Technology Options
The following guidelines will help you to understand how you can use ASP.NET Web Services (ASMX):
- ASPX services can be accessed over the Internet.
- ASPX services use port 80 by default, but this can be easily reconfigured.
- ASPX services support only the HTTP protocol.
- ASPX services have no support for DTC transaction flow. You must program long-running transactions using custom implementations.
- ASPX services support IIS authentication.
- ASPX services support Roles stored as Windows groups for authorization.
- ASPX services support IIS and ASP.NET impersonation.
- ASPX services support SSL transport security.
- ASPX services support the endpoint technology implemented in IIS.
- ASPX services provide cross-platform interoperability and cross-company computing.
REST vs. SOAP
There are two general approaches to the design of service interfaces, and the format of requests sent to services: REST and SOAP.
Representational State Transfer (REST)
This approach encompasses a series of network architecture principles that specify target resource and address formats. It effectively means the use of a simple interface that does not require session maintenance or a messaging layer such as SOAP, but instead
sends information about the target domain and resource as part of the request URI.
This approach serializes data into an XML format passed as values in an XML message. The XML document is placed into a SOAP envelope that defines the communication parameters such as address, security, and other factors.
When choosing between REST and SOAP, consider the following guidelines:
- SOAP is a protocol that provides a basic messaging framework upon which abstract layers can be built. REST is an architectural style that can be implemented over the SOAP protocol.
- SOAP is commonly used as a remote procedure call (RPC) framework that passes calls and responses over networks using XML-formatted messages.
- SOAP handles issues such as security and addressing through its internal protocol implementation, but requires a SOAP stack to be available.
- REST can be implemented over other protocols, such as JSON and custom Plain Old XML (POX) formats.
- REST exposes an application as a state machine, not just a service endpoint. It has an inherently stateless nature, and allows simple standard HTTP calls such as GET and PUT to be used to query and modify the state of the system.
- REST gives users the impression that the application is a network of linked resources, as indicated by the URI for each resource.