Desining Service Layers

J.D. Meier, Alex Homer, Jason Taylor, Prashant Bansode, Lonnie Wall, Rob Boucher, Akshay Bogawat.

Overview

When providing application functionality through services it is important to separate the service functionality into a service layer. Within the service layer you would define the service interface, implement the service interface, and provide translator components used to translate data formats between the business layer and external data contracts. One of the more important concepts to keep in mind is that a service should never expose internal entities used by the business layer. The following diagram shows where a service layer fits in the overall design of your application.

Arch1.JPG

Service Layer Components

  • Service Interfaces. Services expose a service interface to which all inbound messages are sent. The definition of the set of messages that must be exchanged with a service in order for the service to perform a specific business task constitutes a contract. You can think of a service interface as a façade that exposes the business logic implemented in the service to potential consumers.
  • Message Types. When exchanging data across the service layer, business entity components may need to be wrapped into a specific message for communication with the calling services. Message Types are “message contracts” for communication between service consumers and providers.

Approach

The approach used to design a service layer starts by defining the contracts that you plan to expose from your service. Once the contracts are defined the next step is to design the service implementation, which is used to provide a façade into the business layer.

The following steps can be used when designing a service layer:
  • Define the Service contracts that represent operations supported by your service.
  • Define the Data contracts that represent the schema used for messages.
  • Define the Fault contracts used to return error information to consumers of the service.
  • Design transformation objects used to translate between business entities and data contracts.
  • Design a façade used to translate between service contracts and business process components.

Design Considerations

When designing the service layer there are many considerations that you should include in the design. Many of the design considerations are related to proven practices around layered architecture. However, with a service there are message related considerations that you need to take into account. The main thing to keep in mind is that a service uses message-based interaction, which is inherently slower than object-based interaction. In addition, messages passed between a service and consumer can be routed, modified, or lost, which requires a design that will account for the non-deterministic behavior of messaging.
  • Design services to be application scoped and not component scoped. Service operations should be course grained and focused on application operations. For instance, 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 sub-sets of the data with multiple calls.
  • Design Entities for extensibility. In other words, data contracts should be designed so that you can extend them without affecting consumers of the service.
  • Compose entities from Standard elements. When possible you should use standard elements to compose complex types used by your service.
  • Use a layered approach to designing services. Separating the business rules and data access functions into separate components where appropriate.
  • Avoid tight coupling across layers. You should use abstraction to provide an interface into the business layer. The abstraction can be implemented using public object interfaces, common interface definitions, abstract base classes, or messaging. For web applications you should consider a message-based interface between the presentation and business layers.
  • Design without 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 service contract. The implementation of a service should never be exposed to external consumers.
  • Design to assume possibility of invalid requests. You should 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 the service can manage and control repeated messages (idempotency). When designing the service there are patterns you can use to ensure that duplicate messages are not processed more than once.
  • Ensure the service can manage messages that arrive out of order (commutativity). If there is a possibility that messages can arrive out of order you will need to implement a design that will store messages and then process them in order.

Services Layer Frame

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.
Failure to protect sensitive data.
Data Consistency Failure to check for data consistency
Improper handling of transactions in a disconnected model
Exception Management Not catching exceptions that can be handled.
Not logging exceptions.
Dealing with message integrity when an exception occurs
Messaging Channels Not choosing the appropriate message channel
Not handling exception conditions on the channel.
Providing access to non-messaging clients.
Message Construction 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 Routing Not choosing the appropriate router.
Handling a specific item from a message.
Making sure that messages are handled in the proper order.
Message Transformation Unnecessary transformations.
Implementing transformations at the wrong point.
Using a canonical model when not necessary.
REST Limited schema support
Tools for REST are primitive
Using hypertext to manage state
SOAP Choosing the appropriate security model
Planning for fault conditions.
Complex types in the message schema

Authentication

Designing an effective Authentication strategy for your service layer is important from security and reliability of your application. Failing to design a good authentication strategy can make your application vulnerable to spoofing attacks, dictionary attacks, session hijacking, and other attacks.

When designing Authentication, consider following guidelines:
  • 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 SSL are used with basic authentication or when credentials are passed as plain text.
  • Use secure mechanisms such as WS Security with SOAP messages.

Authorization

Designing an effective Authorization strategy for your service layer is important from security and reliability of your application. Failing to design a good authorization strategy can make your application vulnerable to information disclosure, data tampering, and elevation of privileges.

When designing Authorization, consider following guidelines:
  • Set appropriate access permissions on resources for users, groups, and roles.
  • Use URL authorization and/or file authorization when using Windows authentication.
  • Where appropriate, restrict access to publicly accessible Web methods using declarative principle permission demands.
  • Execute services under the most restrictive account that is appropriate.

Communication

When designing the communication strategy for your service, the protocol you choose should be based on the deployment scenario your service needs to support. If the service will be deployed within a closed network you can use TCP for more efficient communications. If the service will be deployed in to a public facing network than you should choose HTTP for the protocol.

When designing communication, consider following guidelines:
  • Use dynamic URL behavior with configured endpoints for maximum flexibility.
  • Validate endpoint addresses in messages.
  • Determine your transport protocol.
  • Determine how to handle asynchronous calls.
  • Decide if the message communication needs to be on-way or two-way.
  • Determine how to handle communication reliability.
  • Determine how to handle idem-potency

Data Consistency

Designing for data consistency is critical to the stability and integrity of your service implementation. Choosing not 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.

When designing for data consistency, consider following guidelines:
  • Validate all parameters passed to the service components.
  • Check input for dangerous or malicious content.
  • Determine your signing, encryption and encoding strategy.
  • Use an XML schema to validate incoming SOAP messages.

Exception Management

Designing an effective exception management solution for your service layer is important from security and reliability of your application. Failing to do so can make your application vulnerable for DoS (Denial of Service) attacks and also might end up revealing sensitive and critical information about your application.

Raising and handling exception is an expensive operation, so it’s important the design also takes into account the performance considerations. A good approach is to design a centralized exception management and logging solution and consider providing hooks into your exception management system to support instrumentation and centralized monitoring to help system administrators.

When designing Exception Management, consider following guidelines:
  • Do not use exceptions to control business logic.
  • Design strategy for handling unhandled exceptions.
  • Design appropriate exception logging strategy.
  • Design appropriate notification strategy for critical errors / exceptions
  • Do not reveal sensitive information.
  • Use SOAP Fault elements or custom extensions to return exception details to the caller.
  • Disable tracing and debug compilation for all services except during development and testing.

Messaging Channels

Communication between a service and it’s consumers is done by sending data through a channel. In most cases you will leverage the channels that are provided by the service infrastructure you plan to use, such as WCF. As a result, you will need to understand what patterns are supported by the infrastructure you are using and determine the appropriate channel for interaction with consumers of the service.

When designing message channels, consider following guidelines:
  • Determine appropriate patterns for messaging channels.
  • Determine how to intercept and inspect the data between endpoints.

Message Construction

When data is exchanged between a service and consumer it needs to be wrapped by a message. The format of that message is based on the type of operations you need to support. For instance, you might be exchanging documents, executing commands, or providing events. With slow messages you should also consider using expiration information in the message.

When designing message construction, consider following guidelines:
  • Determine appropriate pattern for message constructions (command, document, event, request-reply)
  • Break the huge amounts of data into smaller chunks and send them in sequence.
  • Use expiration information for messages that are time-sensitive. The service should ignore messages that it receives after the expiration.

Message Endpoint

The message endpoint represents the connection that applications used to interact with your service. The implementation of your service interface in WCF represents the message endpoint. When designing the service implementation you need to consider the type of message that you are consuming. In addition, you should design for different scenarios related to handling messages.

When designing message endpoints, consider following guidelines:
  • Determine relevant patterns for message endpoints. (gateway, mapper, competing consumers message dispatcher).
  • Determine if you should accept all messages or should implement a filter to handle specific messages.
  • Design for idempotency in your message interface. Idempotency is related to a condition 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 all duplicate messages will be ignored.
  • Design for disconnected scenarios. For instance, you may need to support guaranteed delivery.
  • Design for invalid messages. You should never assume that all messages received are valid.

Message Protection

When transmitting sensitive data between a service and it’s 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 instance, you should encrypt sensitive sections within a message and use signatures to protect from tampering.

When designing message protection, consider following guidelines:
  • If interactions between the service and consumer are not routed through other services than you can use transport layer security such as SSL.
  • If the message passes through one or more servers you should always use message-based protection. With transport layer protection the message is decrypted and then encrypted at each server it passes through, which represents a security hole when only using transport layer security.
  • Use encryption to protect sensitive data in messages.
  • Use digital signatures to protect messages and parameters from tampering.

Message Routing

A message router is used to decouple a service consumer from the service implementation. There are three main types of routers you might use, simple, composed, and architectural pattern based. With simple routers you use a single router to determine the final destination of a message. With composed routers multiple simple routers are combined to handle more complex message flows. Architectural patterns are used to describe different routing styles that are based on simple message routers.

When designing message routing, consider following guidelines:
  • Determine relevant patterns for message routing.
  • If sequential messages are sent from a consumer the router needs to ensure they are all delivered to the same endpoint in the required order.
  • A Message router will normally inspect information in the message to determine how to route the message. As a result, you need to ensure that the router will have access to that data.

Message Transformation

When passing messages between a service and consumer there are many cases where the message needs to be transformed into a format that the consumer can understand. This is normally found in cases where non-message based consumers need to process data from a message-based system. Adapters can be used to provide access to the message channel for a non-message based consumer, and translators are used to translate the message data into the format a consumer understands.

When designing message transformation, consider following guidelines:
  • Determine relevant patterns for message Transformation.
  • Use metadata to define the message format.
  • Consider using an external repository to store the metadata.

Representational State Transfer (REST)

REST represents an architecture style for distributed systems. It is designed to reduce complexity by dividing a system into resources. The operations supported by a resource represents the functionality provided by a service that uses REST.

When designing REST resources, consider following guidelines:
  • Identify and categorize resources that will be available to clients.
  • Choose an approach that will be used for resource representation.
  • Decide if multiple views should be supported for different resources.

Service Interface

The service interface represents the contract exposed by your service. When designing a service interface you should consider boundaries that need to be crossed and the type of consumers accessing your service. For instance, service operations should be coarse grained and application scoped. One of the biggest mistakes with a service interface design is to treat the service as a component with fine grained operations. This results in a design that requires multiple calls across physical or process boundaries, which are very expensive in terms of performance and latency.

When designing a service interface, consider following guidelines:
  • Use a coarse-grained interface that minimizes the number of calls required to achieve a specific result.
  • Be prepared to implement more than one interface to provide a different view of the service to different clients.
  • Design interfaces to allow loose coupling with other layers of the application.
  • Design services interfaces such that changes to the business logic do not affect the interface.
  • Consider implementing multiple service interfaces if the business logic may be accessed in different ways by different clients.
  • Consider implement caching, mappings, and type conversion in the interface if required by the component.
  • Do not implement business rules in a service interface.
  • Use standard formats for parameters to enable maximum compatibility with different clients.
  • Design service interfaces for maximum interoperability with other platforms and services.
  • Choose appropriate technology for implementing your services.
  • Choose appropriate transport protocol, message formats etc for your services

SOAP

SOAP represents a message-based protocol used to implement the message layer of a service. The message is composed of an envelope that contains a header and body. The header can be used to provide information that is external to the operation being performed by the service. For instance, a header may contain security, transaction, or routing information. The body contains contracts used to implement the service in the form of XML schemas.

When designing SOAP messages, consider following guidelines:
  • Define the schema for the operations that can be performed by a service.
  • Define the schema for the data structures passed with a service request.
  • Define the schema for the errors or faults that can be returned from a service request.

Deployment Considerations

When deploying a service layer the goal of a software architect is to consider the performance and security issues in the production environment.

When deploying the service layer, consider following guidelines:
  • Locate the service layer on the same tier as the business layer to improve application performance.
  • If the service is only accessed by other applications within a local network consider using TCP for communications.
  • Configure the service host to use transport layer security only if consumers have direct access to the service.

Pattern Map

Category Relevant Patterns
Authentication Direct Authentication
Brokered Authentication
Federated Authentication (SSO)
Authorization Role Based Authorization
Resource Based Authorization
Claims Based Authorization
Trusted subsystem
Impersonation and Delegation
Communication Fire and Forget
Request Response
Duplex
Reliable Sessions
Data Consistency Atomic Transactions
Cross-service Transactions
Long running transactions
Exception Handling Exception Shielding
Messaging Channels Channel Adapter
Message Bus
Messaging Bridge
Point-to-point Channel
Publish-subscribe Channel
Message Construction Command Message
Document Message
Event Message
Request-Reply
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 Integrity
Data Origin Authentication
Data Confidentiality
Exception Shielding
Federation
Replay Protection
Validation
Message Routing Aggregator
Content-Based Router
Dynamic Router
Message Broker (Hub-and-Spoke)
Message Filter
Process Manager
Message Transformation Canonical Data Mapper
Claim Check
Content Enricher
Content Filter
Envelope Wrapper
Normalizer
REST Behavior
Container
Entity
Transaction
Store
Service Interface Remote Façade
SOAP Data Contracts
Fault Contracts
Service Contracts

Pattern Descriptions

  • Aggregator – Used to collect individual messages that are related or part of a message sequence and combining them into a single message.
  • Atomic Transactions – Transactions that are scoped to a single service operation.
  • Behavior – Applies to resources that carry out operations. These resources have generally no state of their own and only support the POST operation.
  • Canonical Data Mapper – Uses a common data format to perform translations between to desperate data formats.
  • Channel Adapter – Use a Channel Adapter that can access the application's API or data and publish messages on a channel based on this data, and that likewise can receive messages and invoke functionality inside the application.
  • Claim Check – Used to retrieve data from a persistent store when required.
  • Command Message – Represents 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 – Used to enrich a message with missing information from an external data source.
  • Content Filter – Used to remove sensitive data from a message and reduce network traffic by removing data from the message.
  • Content-Based Router – Allows the routing of a message based on contents inside the message.
  • Cross-service Transactions – Transactions that can span multiple services.
  • Data Integrity – Enables the service to ensure that messages have not been tampered with in transit.
  • Data Origin Authentication – Supports the ability to validate the origin of a message, which is an advanced form of data integrity.
  • Data Confidentiality – Use message-based encryption to protect sensitive data in a message.
  • Data Contracts – Used to define the schema for data structures passed with a service request.
  • Document Message – Used for transferring documents between applications.
  • Duplex – Use it for two-way message communication where both - the service and the client - send messages to each other independently whether using one-way or request/reply messaging.
  • Durable Subscriber – Used for disconnected scenarios where messages are saved and then accessible to the client when connecting to the message channel. This can be used to ensure guaranteed delivery.
  • Dynamic Router – Uses conditions and or rules to dynamically route a message between a consumer and service.
  • Entity – Applies to resources that can be read with a GET operation, but can only be changed by PUT and DELETE operations.
  • Envelope Wrapper – Represents a message that is wrapped by an envelope, which contains header information used to
  • Event Message – Used to support asynchronous event notification between applications.
  • Exception Shielding – Prevent a service from exposing information about the internal implementation when an exception occurs.
  • Fault Contracts – Used to define schema of errors or faults that can be returned from a service request.
  • Federation – Provides an integrated view into information distributed across multiple services and consumers.
  • Fire and Forget – Use it for one-way message communication where no response is expected.
  • Idempotent Receiver – Used to ensure that a service will only handle a message once.
  • Long running transactions – Transactions that are part of a workflow process
  • Message Bus – Structure the connecting middleware between these applications as a Message Bus that enables them to work together using messaging.
  • Messaging Bridge – Use a Messaging Bridge, a connection between messaging systems, to replicate messages between systems.
  • Message Broker (Hub-and-Spoke) – Represents a central component used to handle messages from multiple sources and determine the correct destination.
  • Message Dispatcher – Used to support sending messages to multiple consumers.
  • Message Filter – Used to eliminate messages that are not desired as it passes through a channel using a set of criteria.
  • Messaging Gateway – Provide a gateway to encapsulate message-based calls into a single interface in order to separate it from the rest of the application code.
  • Messaging Mapper – Use a messaging mapper to transform requests into business objects for incoming messages and reverse the process to convert business objects into a response.
  • Normalizer – Used to normalize data into a common format when organizations use different formats.
  • Process Manager – Supports a workflow style of routing the message through multiple steps.
  • process the message.
  • Point-to-point Channel - Send the message on a Point-to-Point Channel, which ensures that only one receiver will receive a particular message.
  • Polling Consumer – The service consumer checks the channel for messages at a regular interval.
  • Publish-subscribe Channel – Create a mechanism to send messages only to the applications that are interested in receiving the messages without knowing the identity of the receivers
  • Replay Protection – Used to implement message idempotency by preventing an attacker from intercepting a message and executing it multiple times.
  • Request Response – The message exchange is a request-response pair where every message sent expects to receive a response.
  • Reliable Sessions – Reliable sessions provides end-to-end reliable transfer of messages between a source and a destination, regardless of the number or type of intermediaries that separate the messaging (source and destination) endpoints
  • Request-Reply – Use separate channels to send the request and reply.
  • Selective Consumer – The service consumer uses filters to receive messages that match specific criteria.
  • Service Contracts – Used to define the schema for operations that can be performed by a service.
  • Service Activator – Represents a service that receives asynchronous requests to invoke operations in business components.
  • Store – Allows entries to be created and updated with PUT.
  • Transaction – Resources that support transactional operations.
  • Transactional Client – Supports the ability of a client to implement transactions when interacting with a service.
  • Validation** – Used to protect services from malformed or malicious content.

Technology Considerations

The following technical considerations should be considered when designing a service layer:
  • Use Windows Communication Foundation (WCF) Web services where possible for maximum feature availability and interoperability.
  • Use ASP.NET Web services (ASMX) for simplicity, and only when a suitable Web server will be available

Additional Resources

Last edited Sep 11, 2008 at 6:03 AM by Lon28Wall, version 4

Comments

No comments yet.