If your ERP development plan needs new custom modules to talk to the ERP you already run, use the ERP's published API by default. Add a middleware layer once several systems need the same data, and keep direct database writes off the table almost entirely.
You may be facing a familiar problem. The ERP handles finance, inventory and orders well enough, but the business now needs something it does not do: a customer portal, a field service app, a pricing engine, a supplier dashboard. Your team can build the module. The hard question is how it reads and writes ERP data without turning every future upgrade into a crisis.
How do the three integration options actually differ?
The real difference is who enforces the business rules. With an API or middleware, the ERP still runs its own logic. With direct database access, your code has to do that job, and it usually does it badly.
The ERP's API. Your module calls the vendor's own service layer. Examples include OData services in SAP S/4HANA, SuiteTalk REST in NetSuite, the Dataverse Web API in Dynamics 365 and JSON-RPC in Odoo. When you create a sales order this way, the ERP runs the same validation, pricing, tax, credit checks and posting logic it runs when a person types the order on screen.
Middleware. An integration layer sits between your apps and the ERP. That could be MuleSoft, Boomi, Azure Integration Services, or a small in-house service with a message queue. Underneath, it still calls the ERP's API. What it adds is queuing, retries, field mapping and a single place to see every message that moved.
Direct database access. Your app connects to the ERP's database and reads or writes table rows with SQL. It skips the business logic layer completely.
How do they compare on the things a CTO cares about?
| ERP API | Middleware | Direct database | |
|---|---|---|---|
| Upgrade safety | High. APIs are versioned and deprecations are announced | High. Mapping changes live in one place | Low. Internal tables can change in any release |
| Data integrity | The ERP enforces its own rules | Same as API, plus replay of failed messages | Your code must recreate every rule the ERP runs |
| Vendor support | Supported | Supported, because it uses the API | Often excluded from support |
| How far a failure spreads | One call, one module | Contained. Messages wait in a queue | Can damage shared ledgers used by everyone |
| Speed to first release | Fast | Slower to set up | Fastest, which is the trap |
That last row explains why teams keep choosing the wrong option.
Why are direct database writes the choice teams most often regret?
Because the database is not the ERP. Tables store the results of business logic, but the logic itself lives in application code you cannot see from SQL.
Insert an invoice row directly and you skip everything the ERP normally does around it: number ranges, tax calculation, general ledger postings, open item balances, change logs and approval workflows. The row looks correct. The books are not.
The damage is quiet at first. Nobody notices until month-end close, when the trial balance does not tie out, or an auditor asks why an invoice has no change history. By then the bad records have flowed into reports, payment runs and tax filings, and unpicking them is slow, manual work.
Then the upgrade arrives. Vendors treat internal tables as theirs to change. SAP's move from ECC to S/4HANA restructured core finance and inventory tables, and every integration that wrote straight into the old ones had to be rebuilt. Most cloud ERPs do not give you write access to the production database at all, which tells you how vendors view the practice.
Support is the third problem. Many vendor agreements exclude issues caused by data changed outside the application, so when something breaks, you are on your own.
Reads are a different story. Pulling data from a read replica, a data warehouse or the vendor's reporting views carries far less risk, as long as you accept that internal structures may still shift.
What does getting this wrong cost you?
The first cost is a frozen ERP. Teams with direct database integrations often postpone upgrades because they know the custom modules will break, which means missing security patches and new features for years.
The second is trust in your numbers. When finance cannot rely on what the ERP says, people start keeping spreadsheets on the side, and the system you paid to standardise on loses its point.
The third is a rewrite under pressure. Eventually an upgrade becomes unavoidable, and the integration you built in a few weeks has to be redone against a deadline, while the business waits.
Do you actually need middleware?
Not always. If you have one custom module talking to one ERP at modest volume, middleware is overhead you will maintain for little return.
In that case, call the API directly through a thin client in your module, with retries, timeouts and structured logging. A team that has worked with your ERP's API before can usually handle this without outside help.
Middleware earns its place when three or more systems consume the same ERP events, when you need guaranteed delivery during ERP downtime, when the ERP enforces strict rate limits, or when batch peaks would otherwise flood it.
Which ERP development integration pattern should you pick first?
Work through these rules in order:
- All writes go through the API. If the API does not expose the object you need, extend it with a vendor-supported mechanism: a custom OData service in SAP, a SuiteScript RESTlet in NetSuite, a custom API in Dataverse or a custom Odoo module. Do not reach into tables.
- If more than two systems need the same ERP data, add middleware before the third integration is built, not after.
- If you need heavy reporting reads, use a replica or warehouse. Never run large queries against the live transactional database during business hours.
- If someone proposes a direct write "just for this one table", ask two questions: what happens at the next upgrade, and who rebuilds the ERP rules that the write skips?
What should you ask before you sign off on the design?
This is the list most comparison articles leave out. Each question exposes a specific failure early.
- Which API version are we calling, and how much deprecation notice does the vendor give? This tells you how often you will need to touch the integration.
- What happens if the ERP is unavailable for two hours? If the answer is "orders are lost", you need a queue.
- How will we know a message failed? Silent failures are worse than loud ones. Ask for alerts and a dead letter queue.
- Is every write idempotent? Retries without idempotency keys create duplicate orders and invoices.
- Who owns the field mapping document? Without one owner, mappings drift and nobody can explain a mismatch.
- Does anything write to the database directly? If yes, get it in writing why, and plan its removal.
Geminate Solutions has shipped 50+ products, many of them modules built around systems the client already depended on, and the API-first rule above is the one we hold to.
If you are planning custom modules around an existing ERP, you can ask Geminate Solutions for a free review of your integration plan. We sign an NDA before we talk and reply within 24 hours.
Top comments (0)