Showing posts with label endpoint. Show all posts
Showing posts with label endpoint. Show all posts

Thursday, March 27, 2008

Decomposing Services

In my last post, I discussed how a service exposes one or more endpoints. But how many endpoints should a service expose? What is the rationale for exposing more than one endpoint?

The purpose of a service endpoint is to provide access to functionality exposed by the service. The functionality exposed is determined by the syntax and semantics of the messages exchanged via that endpoint.

The binding/policy of the endpoint determines the service level agreements (SLAs) (such as messaging reliability and performance) upheld by the service, as well as the demands made of the consumer in order to successfully communicate with the service (such as message security).

A service may be decomposed into multiple autonomous components. This is not a component in the traditional sense. That is, it is not a single .NET assembly or Java package. It is an entire horizontal partition of a service. An autonomous component comprises an endpoint, business logic and data. To the consumers of a service, it is assumed that no data is shared between the autonomous components of a service.

Being part of the same service, autonomous components may share the same domain model, and consequently may share the same database schema. That being said, they may or may not in fact share the same physical database. If they use different physical databases, those databases may or may not share the same schema.

So for example, we may have one autonomous component responsible for dealing with standard customers, and another responsible for dealing with VIP customers. Although the functionality exposed by each component may in fact be identical; by separating the service into two autonomous components, we give the ability to provide different SLAs for service consumers dealing with VIP and non-VIP customers. For example, we may use an unsecured HTTP transport for the non-VIP customers, and a secured MSMQ transport for the VIP customers.

Note that the VIP and non-VIP customer data although sharing the same structure and business rules, are not in fact sharing the same physical data. If the two autonomous components were to share the same database, we would be dealing with separate database records for the VIP and non-VIP customers.

As another example, we may decide to have separate autonomous components for different product lines supported by a service. In this case, each component would likely have a different domain model (and database schema); although there may be some structural aspects in common.

For instance if we were dealing with different insurance product lines, we may have information common to every policy across all product lines in a table whose structure was common to every autonomous component; while maintaining the flexibility to have independent structures for each product line in tables whose schemas are not shared between autonomous components.

In conclusion, there is no value in arbitrarily exposing multiple endpoints for a service. But rather we should define multiple endpoints where there is a need for decomposing a service into autonomous components, assigning each autonomous component its own endpoint.

Wednesday, March 26, 2008

What is an Endpoint?

For a while now I've been describing the various ins and outs of services using the term endpoint, assuming that the term was well understood by my readers. Although this may be the case for many readers out there, there are many subtleties around the definition of an endpoint that are worth discussing.

Services communicate with each other by way of exchanging messages. Messages travel between services via a channel. An endpoint either sends messages onto or receives messages from a channel. All messages arrive at or leave a service via an endpoint.

Note that although a channel has two or more endpoints, it only has one address. The address is controlled by the service that defines/owns/controls the channel. But with potentially many services communicating over a given channel, who owns the channel?

Well that depends on the type of channel. In the case of a point-to-point channel (one service sending a message to one other service), the receiving party controls the channel. In the case of a publish-subscribe channel, the publishing party controls the channel.

We define the endpoints of a service to be only the endpoints of channels controlled by that service. That is, only the endpoints attached to channels owned by a service are described in that service's contract.

A service endpoint is defined by three components:

  • The schema of the messages that pass through the endpoint
  • The binding and policy (which describe the channel - that is, the means by which messages are transported)
  • The address of the channel used by the endpoint to receive or publish messages

Note that each combination of schema, binding/policy and address determines a unique endpoint. So if a service can receive the same messages via HTTP and MSMQ, then we have two distinct endpoints - one for each transport. Alternatively we could have two different endpoints on the same transport accepting different messages.

One catch though is that a service contract may or may not contain service instancing information. That is, it may or may not contain the endpoint addresses. The argument here is that a service shouldn't really care where it is deployed, so that information shouldn't really appear in its contract. We should be able to move a service without updating its contract.

In scenarios where a service registry is being employed, the service registry will contain the service instancing information and the service contracts will contain only the schema, binding and policy metadata.