Edward, thanks for an excellent article. The vast majority of things we do on computers can be described as implementing state changes in data. It is reasonably easy to declare the constraints for valid states for most data structures. Only very rarely do we really need imperative statements to effect those changes.
For more than a decade, I've been using the passing of REST messages as my only application-level APIs. That has presented me with no added issues or complexities and fits the microservice architectural pattern very comfortably.