Don’t Tie Me Down
All of the mechanisms we’ve discussed so far have been for designing tightly coupled systems. These are typically easier to design but less flexible than loosely coupled systems.
In a loosely coupled system, services are typically advertised and discovered on the fly. A simple example of this is the World Wide Web. When you clicked a link to come here, a DNS query was performed, translating the hostname to an IP address, identifying the server. Your web browser then connected to the InformIT web server and downloaded this page. The web browser and server were developed independently of each other, but two things allowed them to interoperate:
- A well-defined service discovery mechanism—in this case, connecting to TCP port 80. This requirement is easy to meet. You can use a fixed port for your service if it’s networked, or a fixed location for a UNIX domain socket if it’s local. A good example is PostgreSQL, which places a UNIX domain socket in /tmp for clients to connect to.
- A well-defined protocol for exchanging information—in this case, HTTP. This requirement can be met by adopting an existing protocol (such as HTTP, or, at a higher level, something like XML-RPC), defining a new one, or providing a client library. The client library will export a set of functions that allows a developer to interact with your system without knowing how the serialization works. The advantage of this approach is that it allows you to change the wire protocol easily. As long as the client library version matches the server, things will still work.