Mobile apps
One Laravel API, web and mobile: how we structure it
Keep every business rule in the API, and treat web and mobile as two clients that ask questions and show answers. The extra work is in authentication, app versions and slow connections.
By itmarkerz Technologies. Updated 30 October 2026.
The project
Our UK garage-booking SaaS has this shape: a Laravel API, a Next.js web application for garages and customers, and React Native apps for iOS and Android. Car owners pick a slot, pay and receive invoices and reminders on their phone. Garages manage services, slots and customers. It took about a year as one product, and it is multi-tenant, since many garages subscribe. Code samples here are illustrative rather than taken from that project.
What goes where
| Concern | Laravel API | Next.js | React Native |
|---|---|---|---|
| Is this slot free? | Decides, inside a transaction | Asks and displays | Asks and displays |
| What does this cost, with VAT? | Calculates and stores | Displays | Displays |
| May this user see this? | Enforces with policies | Hides what isn’t allowed | Hides what isn’t allowed |
| Reminders | Schedules and sends through queues | Preferences screen | Receives the notification |
| Form validation | Final say | Early feedback | Early feedback |
| Screen and navigation state | No part | Owns | Owns |
The test is simple. If a rule would have to be written twice, once in TypeScript for web and once for mobile, it belongs in the API. Client-side validation is a courtesy. A phone can be running an old build, and anyone can call your API directly.
Authentication differs by client
The browser and the phone are different security environments. Laravel’s Sanctum covers both: cookie-based sessions for a first-party web front end, and API tokens for mobile apps.
// Mobile login: one named token per device
$token = $user->createToken($request->device_name, ['bookings:write']);
return ['token' => $token->plainTextToken];Naming a token per device gives users a “signed-in devices” list and lets you revoke a lost phone. Store the token in the device’s secure storage, not in plain async storage. Remember that a Next.js server calling the API on a user’s behalf is a third case, and it should forward that user’s identity rather than use an all-powerful service key.
Old apps keep calling you
The website updates for everyone when you deploy, and phones don’t. Some users will run an old build for months, so an API change that is safe for your web app can break them. Three habits help:
- Add, don’t change. New fields are safe. Renamed fields and tightened validation aren’t.
- Version the routes, such as
/api/v1, and only introducev2when you must. Each version is code you have to keep. - Include a minimum version check. The app sends its build number, and the API can answer “please update”. Build this into your first release. It can’t be added to versions already installed.
Designing for the phone
The same API has to be pleasant on poor mobile signal. Use API resources so responses contain what a screen needs and no more. Use cursor pagination for long lists, so new records don’t shift pages as people scroll. Make payment and booking requests idempotent, using a client-generated key, because a phone that loses signal will retry, and you don’t want two bookings. Send a notification for slow results, rather than keeping a phone waiting on a held request.
Multi-tenant scoping
With many garages on one platform, every query must belong to a tenant. Put this in a global scope or base query, so a forgotten clause doesn’t expose someone else’s customers, then write a test that tries it. A car owner may also use more than one garage, so decide early whether accounts belong to a garage or to the platform. That decision is hard to change later and affects login, data ownership and what you say about privacy.
Test the contract
With separate clients, the API is a contract between teams. Laravel feature tests can pin response shapes, and a shared OpenAPI description lets the Next.js and React Native code generate types from one source. When someone changes a response, the failure then appears in CI and not in an app store review. This structure also means the mobile route can change later, as we discuss in wrapped web app or React Native.
The product described here
UK garage-booking SaaS: car owners book, pay, receive invoices and reminders from their phone; garages manage services and slots. Laravel API, Next.js web app, React Native iOS/Android apps. About one year.
- Sector
- Automotive
- Region
- UK
- Stack
- Laravel, Next.js, React Native
- Engagement
- Product build, about one year
Questions
Should mobile and web use the same endpoints?
Mostly. Share the endpoints and the rules behind them. Add a mobile-specific endpoint only where a screen would otherwise need many calls on a slow connection, and keep it a thin combination of existing actions.
Do we need GraphQL for this?
Not necessarily. A well-designed REST API with Laravel's API resources works for most products, and it is what most Laravel teams already know. Consider GraphQL if many clients need very different shapes of data.
More on mobile apps
- Wrapped web app or React Native? We've shipped bothA decision table from a three-month wrapped app and a year-long React Native SaaS.
- Getting a wrapped app through store reviewWhat Apple and Google publish about repackaged websites, and what to build.
- Expo or bare React Native?What React Native's own docs recommend, and when you'd still manage native folders.
- Upgrading an older React Native appThe support window, the New Architecture and an order of work.
Planning an app alongside your web product?
Tell us what exists today and which clients you need. We will tell you what your API needs before a mobile team starts.
We reply within one business day (IST).