The question we get on every kickoff
“We assumed the new API layer would be GraphQL. Everyone we spoke to pitched GraphQL. You’re the first vendor telling us REST is the right answer, and we want to understand why before we agree,” a platform architect at a top-5 European insurer told us at kickoff last quarter. His question lands on 23 of our last 30 migration engagements within the first hour. The answer is always the same: GraphQL fits some problems. Oracle Forms migration is not one of them.
This post lays out why, based on what we’ve measured across 14 production deployments.
I remember a 2013 project where we inherited a half-finished SOA layer that some external consultancy had wrapped around an Oracle Forms backend — SOAP envelopes carrying XML fragments that had been hand-shaped to mirror the form blocks. The day we tried to add a single new field to an order line, we found 11 XSDs, four WSDLs, and a Java service bus all needing coordinated changes. It took us six weeks to undo, and it cemented a rule I’ve kept ever since: the API shape should follow the domain, not the latest architectural fashion.
What the source system actually looks like
An Oracle Forms application is a collection of screens, each bound to a small number of database blocks. A block maps to a table or view. Queries are parameterized, result sets are bounded, and navigation between screens passes a handful of keys. The access pattern is narrow, predictable, and already described by the original .fmb files.
The median screen in our sample talks to 2.3 tables and runs 4 distinct queries. The 95th percentile hits 11 tables and 19 queries. This isn’t a domain where clients need to compose arbitrary graphs on the fly.
REST maps to the existing shape
Every block, trigger, and LOV in a migrated form has a direct REST equivalent:
GET /api/orders?status=open®ion=EU
GET /api/orders/{id}
POST /api/orders
PATCH /api/orders/{id}
POST /api/orders/{id}/approve
GET /api/lov/customers?q=acm
The generator produces one endpoint per block query, one per LOV, and one per named PL/SQL action. The OpenAPI specification falls out of the JSON descriptor automatically. Every endpoint is typed end-to-end because the types come from the original database schema, not from a hand-written resolver layer. The underlying architectural style follows Roy Fielding’s original REST dissertation, which is also why cache semantics and statelessness are properties we can actually rely on.
The GraphQL cost nobody talks about
GraphQL’s appeal, per the official specification, is flexibility. Clients ask for exactly the fields they need, joins happen server-side, and over-fetching disappears. For a migration, those benefits show up as costs:
- N+1 resolution. Forms screens issue predictable joins. GraphQL resolvers have to reconstruct those joins at runtime, and DataLoader batching adds a layer that didn’t exist in the source system.
- Authorization surface. SOX-scoped applications need field-level access control. REST endpoints encode permissions at the route level; GraphQL pushes them into every resolver. We measured a 3.2x increase in auth-related code in a prototype GraphQL port.
- Query complexity limits. Production GraphQL servers need depth limits, cost analysis, and persisted queries to prevent abuse. None of this is needed for a known set of migrated screens.
- Caching. REST responses cache cleanly at the CDN and browser layer. GraphQL POST bodies don’t.
The audit argument
Oracle Forms migrations are frequently in scope for SOX, HIPAA, or similar regimes. Auditors review API surfaces. A REST API with 240 endpoints and a published OpenAPI document takes a day to walk through. A GraphQL schema with 80 types and arbitrary query composition takes a week — and the auditor still has questions about which client queries are actually possible in production.
On one utility migration, the audit team explicitly asked for REST because their existing control matrix was built around HTTP verbs and URL patterns. Rebuilding it for GraphQL would have pushed the SOX sign-off by a quarter.
Where GraphQL would make sense
We’re not religious about this. GraphQL is a good fit when clients are heterogeneous, the schema is broad, and query shapes are unpredictable — mobile apps pulling from a product catalog, for instance. Oracle Forms migrations are none of those things. The clients are known (the migrated screens), the schema is bounded (the database the Forms app already uses), and the queries are enumerated in the .fmb files themselves.
Choosing REST here isn’t conservatism. It’s matching the tool to the shape of the problem.
The takeaway
Every endpoint in our generated stack is REST, documented in OpenAPI, and derived directly from the original Forms metadata. The decision isn’t about which API style is better in the abstract. It’s about which one maps cleanly to 30 years of screen-bound database access, and which one auditors can sign off on before the first screen goes live.