Being safe with external services
We all know most apps usually have some integration with an external service. Whether it’s about sending mails/SMSs, or sending sensitive data to CRM, or handling payments, or requesting cargo services, etc.
Let's imagine we have to integrate the 3rd party messaging service Nexmo. One of the easiest ways to achieve this would be to create a class that is responsible for all the communication between our app and Nexmo.
However, we now must make sure that we mock this class in all our tests that will ever run a code which will interact with our Nexmo class. We also must make sure that every developer who is working/will work on the project knows about all the places this code will be executed, and simply not do it. Because that would obviously send a real SMS and we will have to pay for it. And you can imagine what will happen if for example your app supports bulk actions like this.
Luckily, there is a fairly easy way to make sure all these scenarios never happen. We just create an interface for our Nexmo class, with all the public methods out there. And we implement that interface from another, dummy, class which only write to the logs. The final step is to instruct the container to resolve the real Nexmo implementation only for our production environment.
It’s just few extra lines of code, but the amount of peace they bring me is insane. Especially for cases where the external service is a payment processor, or is charging per usage, or is a service which operates with sensitive data of any kind.
It's also worth mentioning there are other benefits by using the approach above. The biggest of which is our codebase will deal with variables called $smsProvider, and not be bloated by a name of a service (in our example Nexmo). Which makes it extremely easy if we have to substitute Nexmo for a different SMS provider, and also make the code more readable because we don't assume everyone knows what Nexmo (or whatever the 3rd party service is called) is.