Once you have decided to integrate two systems rather than merge them, a second decision follows immediately, and it is made far too casually: how the two systems actually connect. There are two answers. One is to have your code read and write the other system's database tables directly. The other is to go through whatever documented interface the other system exposes. We choose the interface, every time, and it is worth saying why, because the database route is genuinely tempting.
Why direct database access is tempting
It is faster to build. There is no interface to learn, no authentication to negotiate, no rate limit to respect, no pagination to handle. The tables are right there, and a query against them is the shortest path from problem to working demo. For a developer under deadline, that shortest path is a strong pull.
Why it is a trap
- A database schema is not a contract. The interface a vendor publishes is something they have committed to keep stable. The table layout is something they reserve the right to change in any release, without announcement, because it was never meant to be a public surface. Depend on the tables and you have coupled to the part of the system most likely to move under you.
- You bypass every rule that sits above the tables. Validation, computed values, access control, side effects: the application layer enforces all of it, and the tables are just storage. Write to the tables directly and you write data the application would have rejected, corrected, or reacted to. You have not integrated with the system; you have corrupted it from underneath.
- You inherit its locking and consistency behaviour with none of its safeguards. The application knows how to touch its own tables safely. Your raw queries do not.
What the API boundary costs, honestly
It costs more up front, and pretending otherwise is how teams get talked back into the database shortcut. You learn the interface. You handle authentication, pagination, rate limits, and error responses. The integration takes longer to stand up. That cost is real. The trade is straightforward: pay a known, bounded cost now, or pay an unbounded and unpredictable cost later, when the schema you depended on changes and the integration fails, often silently, in production.
When there is genuinely no interface
Some systems expose nothing usable, and then the database may be the only boundary available. If so, treat it as a hostile boundary. Read only, never write. Isolate every query that touches the foreign schema inside one module, so the blast radius of a schema change is a single file. And write down, explicitly, that this is a known liability, so it does not get mistaken for a normal integration by whoever maintains it next.
The note for the file
An integration boundary is a contract, and a contract has to be made of something the other party agreed to keep. A published interface is that. A table layout never was. The database shortcut saves a week now and mortgages every upgrade the other system will ever ship.