Beneath the hosting layer sits the service layer. The hosting layer took care of mundane chores like reading configuration files and starting processes. The hosting layer ensures that the service has a good home to live in. Inside the service layer is a collection of clever tricks that give the illusion that building a distributed system does not require using clever tricks. There are 3, 4, or 5 clever tricks that make up the service layer depending on your minimal threshold for cleverness.
The service layer has a contract that describes how two parties interpret each other’s messages. A service contract consists of a collection of operations. Each operation has its own operation contract. An operation contract is a test that determines whether the contents of a message are suitable for use with a particular logical operation. Contracts are used to get around the problem that everyone disagrees about how to authoritatively unify all of the world’s type systems. The two sides don’t have to agree on types as long as they both agree that any messages meet their interpretation of the contract.
The service layer has a collection of endpoints that describe various ways in which the service projects out into the world. The service contract of course does not actually exist outside of whatever program is using it. The sender and receiver can be using entirely different contracts as long as the operation tests defined by those contracts happen to have the same outcome for every message that the two sides try to exchange. What actually requires agreement is that the two sides have some way of sending each other messages over a networking mechanism. An endpoint specifies how a message moves from Point A to Point B without trying to explain what A meant when it sent the message to B.
The service layer has a proxy and dispatcher that makes it seem like the service contract actually exists. A proxy hides the fact that messages need to be exchanged when the client wants to perform one of the operations in the service contract. A dispatcher hides the fact that messages need to be exchanged when the server wants to implement one of the operations in the service contract. The proxy and dispatcher sides do not have to agree on the programmatic model for the operation as long as they agree on the outcome of the operation. The operation can have different names on each side. The operation can have different types on each side. The operation can have different invocation patterns on each side. There are many contracts that can mutually validate a particular sequence of messages.
The service layer has a pumping mechanism that hides the exchange of messages behind the contract. Something has to actually move the messages from the proxy through the endpoint and something has to equally move the messages through the endpoint to the dispatcher. The part that impels operations is the message pump. The conduit that the messages move through is the messaging layer, which is tomorrow’s topic.
Next time: Pieces of the Messaging Framework, Part 3