Export services via port binding
There’s an awful lot wrapped up in what seems at first blush to be a very simple concept here. Taken at face value you could interpret this to mean that you should be building a network app, and that’s true - but let’s unpack that for a bit.
Your application should - when executed in some simple, well-understood way - communicate with the outside world in one of two ways. Traffic initiated by the application should be sent to one or more backing services as previously discussed, and contact with your application from the outside should be received through connections to a network port opened by your application (ideally a port configured in the environment for flexibility, although that’s not strictly speaking a requirement). That’s it.
Of course that’s not the only way that your application can receive information - it can and probably will reach out to other services and components for data, using them as backing services and connecting to them by using the configuration information stored in the environment.
The key take-away here is that there shouldn’t be any other ways that it gets triggered - no shared memory interfaces, no custom signal processing beyond a clean shutdown, and so on. Receiving messages from a bus is fine, but that should be triggered by the application reaching out for a connection, not assuming some form of inter process communication that can come out fo the blue.
Keep Things Simple
This principle is fairly simple, but deceptively important. Since we’ve already agreed that backing services are defined by the environment, by restricting your application to a single method of inbound communication we’ve now completely boxed in the possible touchpoints for testing.
That’s kind a big deal.