We decided to move from (micro)services to a Django monolith, so we consolidated our services there. We added pre-commit hooks so that nobody could call the internals of each app, only a strongly-typed interface that each app exposes (in a file called api.py).<p>This way, if any one service changes its API, the developer can just see what breaks and change all dependents. API changes are atomic, so we don't need any API migrations or versioning, and it's much, much easier to document API functions that are strongly typed with the appropriate types than HTTP calls.<p>The tooling is also great, to deploy a new application you just run the Django `startapp` command and that's it. You get authentication, background processes, events, linters, etc for free. It's very convenient, you don't even need to talk to infra.<p>So far so good.