Backend and APIs / REST and GraphQL
REST and GraphQL API Development Company for Mobile Apps
We are a REST and GraphQL API development company that designs the contract between your app and everything behind it. This page is the detailed view of the API work inside our mobile app backend development service: when to choose REST or GraphQL, how we version so old app builds keep working, how we paginate and cache for slow networks, and the security controls every endpoint gets before launch.
- REST or GraphQL chosen per product
- Old app versions keep working
- Spec-first, with generated clients
- Security checks on every endpoint
Why mobile APIs need different rules
A web front end updates the moment you deploy. A mobile app does not. Users keep old builds for months, store review adds days to every fix, and some devices never update at all. That one fact drives most of our API design: the server must keep serving every app version you still support, and the app must cope when the server changes.
Mobile networks add the rest. Requests drop halfway, a train tunnel turns a 200 ms call into a timeout, and every extra round trip costs battery. So we design for few, well-shaped requests, safe retries and responses that can be cached.
The API is also the part of your system that outlives any single app. A good contract lets you rebuild the app in a new framework, add a web client or open an integration to a partner without touching the backend. A bad one makes each of those a rewrite.
REST vs GraphQL: a decision table
Neither is better in general. REST with an OpenAPI specification is our default for most apps; GraphQL earns its place in specific conditions.
| Factor | REST (with OpenAPI) | GraphQL | Lean towards |
|---|---|---|---|
| Screens need differently shaped data from the same objects | Several endpoints or custom views | Client asks for exactly the fields it needs | GraphQL |
| HTTP and CDN caching | Simple: URLs, ETags, Cache-Control | Harder: mostly POST; needs persisted queries or client cache | REST |
| Several clients (iOS, Android, web, partners) | Works well with versioning | Strong: one schema serves all | Either; GraphQL if shapes diverge a lot |
| Public or partner API | Familiar to most integrators | Needs query cost limits and more onboarding | REST |
| File uploads and downloads | Straightforward | Usually handled outside GraphQL with signed URLs | REST |
| Real-time updates | WebSockets or server-sent events alongside | Subscriptions in the spec | Either |
| Monitoring and rate limiting | Per endpoint, simple | Per operation; needs query cost analysis | REST |
| Team experience | Universal | Needs schema design and resolver performance skills | Depends on your team |
A hybrid is common: REST for auth, files, payments and webhooks, GraphQL for the read-heavy product screens. We record the choice and the reasons in an architecture decision record in your repository.
Versioning so old app builds never break
Our rule: additive changes are free, breaking changes cost a version. Adding a field or a new endpoint ships any time. Renaming, removing or changing the meaning of a field means a new version, while the old one keeps running.
For REST we version in the path (/v1/, /v2/) because it is visible in logs, easy to route and easy to retire. For GraphQL we evolve one schema: new fields are added, old ones are marked deprecated, and we track which app versions still query them before removal.
Every request carries the app version and platform in a header. That gives you usage numbers per version, so you know when an old version is safe to switch off, and it powers a minimum-supported-version check. When you must force an upgrade, for example after a security fix, the API returns a clear response that the app turns into an update screen rather than a crash.
Versioning rules we apply
- Additive changes never need a new version
- Breaking changes get a new version or field
- App version and platform sent on every call
- Deprecation dates agreed and logged
- Minimum supported version enforced by the API
- Old versions retired only when usage is near zero
Pagination, payload size and caching
Pagination
Every list endpoint is paginated from day one, even if it holds ten items at launch. We prefer cursor pagination (an opaque cursor plus a limit) over page numbers for feeds and anything that changes while the user scrolls, because offset pagination skips or repeats items when new rows arrive. Page numbers are fine for admin tables and stable reports.
Payload size
Mobile screens need fewer fields than a database row holds. We shape responses per screen, compress them, send image URLs at the right size rather than the original upload, and avoid nesting that forces the app to download the same object five times.
Caching
For REST, cacheable responses get Cache-Control headers and ETags, so the app can ask “has this changed?” and receive a tiny 304 response instead of the full payload. Public reference data can sit behind a CDN. For GraphQL, we use persisted queries so common operations can be cached by ID, and a normalised client cache on the device. On top of that, the app stores the last good response locally so screens open instantly and refresh in the background.
Planning an API for a new or existing app?
Send us your screens or feature list and the clients that will use the API. Within one business day we will reply with a REST, GraphQL or hybrid recommendation and the main design risks.
API security controls on every endpoint
These are in place before the first public release, whether the API is REST or GraphQL.
- Short-lived access tokens with refresh tokens that can be revoked per device
- OAuth 2.0 with PKCE for native app sign-in, as RFC 7636 defines
- Authorisation checked on the server for every object, not only every endpoint, so user A cannot read user B’s order by changing an ID
- Input validation against the schema; unknown fields rejected
- Rate limits per user, per IP and per API key, with clear retry-after responses
- GraphQL query depth and cost limits, introspection disabled in production
- Idempotency keys on payments, orders and other writes that must not repeat
- No secrets in the app binary; third-party keys stay on the server
- Optional device attestation with Apple App Attest and the Play Integrity API for high-value endpoints
- TLS everywhere, with certificate pinning where your risk profile justifies it
- Audit logs for sensitive actions, without tokens or personal data in plain text
Errors, retries and idempotency
The app needs to know what to do with each failure, so errors follow one format across the API: a stable machine-readable code, a human message, and a field list for validation errors. The app branches on the code, never on the message text.
Retries are safe by design. Reads can always be retried. Writes that create something carry an idempotency key generated on the device; if the same key arrives twice, the server returns the original result instead of creating a second order or charging the card again. This is what lets the app retry automatically after a dropped connection without asking the user.
For long-running work (reports, video processing, AI calls) the API accepts the job, returns an ID, and notifies the app by push or polling when it is done, rather than holding a request open for a minute.
How our REST and GraphQL API development company works
Spec-first, so the app and the backend can be built at the same time.
Discovery (one to two weeks)
Screens, clients, data model and integrations reviewed. Output: REST, GraphQL or hybrid decision, API outline, backlog and a fixed price.
Write the contract
An OpenAPI document or GraphQL schema in your repository, reviewed by the app developers before any server code.
Mock server and generated clients
App developers build against a mock server, using typed client code generated from the contract for Swift, Kotlin, Dart or TypeScript.
Implement in two-week sprints
Endpoints built behind contract tests in CI, so a server change that breaks the spec fails the build, not the app.
Security and load testing
Authorisation tests per role, rate-limit checks and load tests on sign-up, feed, search and checkout before launch.
Document and hand over
Published reference docs, example requests, runbooks and dashboards, with ongoing support available.
Related backend services
APIs need somewhere to run: our cloud backend setup and hosting page covers environments, client-owned accounts and cost controls. Apps that must reach ERP, CRM or HR systems need an integration layer, covered under enterprise app integration. Most APIs also serve an internal back office; see admin panel and dashboard development. For a server stack, Node.js and Laravel are the two we use most, and our guide to the best backend for mobile apps compares the wider options.
APIs we have designed
[[Add 1–3 case studies: REST, GraphQL or hybrid and why, clients served, traffic handled, versioning approach and outcomes the client has approved for publication.]]
[[Add a verified quote from a CTO or lead developer, with written permission.]]
REST and GraphQL API FAQs
Should my mobile app use REST or GraphQL?
Use REST with an OpenAPI specification if your screens map well to resources, you want simple HTTP caching or you will open the API to partners. Choose GraphQL when many screens need differently shaped data from the same objects, or several clients need very different views. A hybrid, with REST for auth, files and payments, is common and sensible.
How do you stop API changes from breaking old app versions?
Additive changes ship freely, while breaking changes go into a new REST version or a new GraphQL field, with the old one kept running. Every request reports the app version, so we can see who still uses an old endpoint. A minimum-supported-version check lets you force an upgrade cleanly when a security fix requires it.
Can you build an API for an app that already exists?
Yes. We document what the current app sends and expects, write a contract that matches it, and build the new API to serve both old and new builds. If the app currently talks straight to a database or backend-as-a-service, we can move one feature at a time behind the new API to avoid a risky big-bang switch.
Is GraphQL less secure than REST?
Not inherently, but it needs extra controls. Because clients compose their own queries, a GraphQL API needs query depth and cost limits, per-field authorisation and, in production, introspection turned off. Persisted queries help by allowing only known operations. With those in place, GraphQL can be as safe as a well-built REST API.
Will we get API documentation?
Yes. The OpenAPI document or GraphQL schema lives in your repository and is the source of truth, so docs never drift from the code. We publish human-readable reference docs with example requests and responses, and generate typed client libraries for your app’s language so a new developer or agency can start working with the API on day one.
How long does it take to build a mobile app API?
Discovery takes one to two weeks and produces the contract outline and a fixed price. Because we work spec-first, the app and API are built in parallel during the same two-week sprints, so the API rarely adds calendar time on its own. The number of integrations and the complexity of permissions are the main drivers of effort.
Get an API contract before you write the app
Book a 30-minute architecture call. Bring your screens and clients, and you will leave with a REST or GraphQL recommendation, a versioning plan and the security controls your API needs.
