How Apps Actually Work
A guide for someone who already understands APIs.
After this lesson you can explain
- What happens when a user taps "order" in an app, and why the backend cannot tell an app from a browser or a Python script.
- Why mobile clients push an API towards idempotency keys, "what changed since X" endpoints, and long backwards compatibility.
- How an app release differs from a web deploy, and why crash reporting and feature flags exist.
1. The mental model: apps are API clients
The single most useful frame: a mobile app is just another client for the same APIs a website uses. When you tap "order" in the McDonald's app, the app sends an HTTPS request with a JSON body to a REST endpoint, gets a JSON response, and renders it. The backend neither knows nor cares whether the request came from a browser, a Python script, or a Kotlin app.
This is why companies invest in good APIs: one backend serves the website, the Android app, the iOS app, and partner integrations. Everything about status codes, auth headers, pagination, and error handling transfers directly. The app is "just" a frontend with different rendering technology.
Browser ─────────┐ Android app ──────┤──► HTTPS + JSON ──► The same API backend ──► Database iOS app ──────────┤ Python script ────┘
2. Anatomy of a native app
Four layers, roughly:
UI layer
Instead of HTML/CSS, screens are declared in the platform's UI toolkit: Jetpack Compose (Android/Kotlin), SwiftUI (iOS/Swift), or a cross-platform equivalent (Flutter widgets, React Native components). Conceptually similar to templating, but reactive: the UI is a function of state, and re-renders automatically when state changes.
Networking layer
The equivalent of Python's requests: Retrofit/OkHttp on Android, URLSession on iOS, dio in Flutter. Same verbs, same headers, same JSON parsing.
Local storage
The big difference from the web. Apps are expected to work with a flaky or absent connection, so they keep a local database (usually SQLite) and sync with the API when online. A lot of real app complexity lives in this sync logic: what happens when the user did something offline and the server state changed in the meantime.
Platform services
Push notifications, location, camera, background jobs. These go through OS-level APIs and permission prompts, and each has its own registration dance. Push, for instance, means your backend stores a device token and sends to it via Google's FCM or Apple's APNs, never directly to the phone.
3. Auth works differently
Websites typically use cookies and sessions (or magic links that set a cookie). Apps don't really do cookies; the standard pattern is token-based auth:
- Log in once; receive an access token (often a JWT) plus a long-lived refresh token.
- Store them in the platform's secure storage: Keychain on iOS, Keystore on Android. Never in plain files or preferences.
- Attach
Authorization: Bearer <token>to every request. - When the access token expires, silently exchange the refresh token for a new one.
This is the same OAuth-shaped world API books cover, with a different storage location. One nuance: apps stay logged in for months, so refresh-token rotation (each refresh issues a new refresh token and invalidates the old one) matters more on mobile than on the web, because a leaked long-lived token is a bigger prize.
4. The lifecycle is hostile in ways the web isn't
A web page either exists or doesn't. A mobile app gets backgrounded, frozen, killed by the OS to reclaim memory, and resurrected, sometimes mid-flow. Well-built apps save state constantly and restore it seamlessly; the user should never notice their app was killed while they were in another app.
The OS also throttles background work aggressively to protect battery life. "Sync while the app isn't open" is genuinely hard, and push notifications are often used as a workaround: the notification wakes the app so it can fetch fresh data.
Why this matters to an API designer: mobile clients reconnect after long gaps, retry aggressively on flaky networks, and replay queued offline actions. APIs that serve mobile apps well tend to need idempotency keys (so a retried order isn't a duplicate order), efficient "what changed since timestamp X" endpoints, and tolerant auth expiry handling.
5. Shipping is a pipeline, not a push
Where a website deploys with a git push, an app release looks like:
- Bump the version number.
- Build a signed bundle. The signing key proves authorship; losing it is a serious problem, so it lives in secure storage or the store's managed-signing service.
- Upload to the Play Console / App Store Connect and wait for review (hours to days).
- Staged rollout: release to 5% of users, watch the crash-rate dashboards, ramp to 100% only when the numbers hold.
Because you can't instantly fix a bad release, mobile teams lean hard on two things:
- Crash reporting (Crashlytics, Sentry): every crash in the field is captured with a stack trace and phoned home.
- Feature flags: code ships dark and is switched on remotely, so turning a broken feature off doesn't need a new release or a review cycle.
The API consequence: old app versions linger on users' phones for months, so the API behind an app must stay backwards-compatible far longer than one behind a website. This is exactly why API versioning (/v1/, /v2/) exists and why breaking changes to a mobile-serving API are a big deal.
6. Money, briefly
| Model | How it works | Store cut? |
|---|---|---|
| Paid up front | Pay once to download. Nearly dead outside niche tools and games | Yes (15–30%) |
| In-app purchases / subscriptions | Free download, paid digital upgrades or recurring plans. Dominates serious app revenue | Yes; subscriptions drop to 15% after a subscriber's first year |
| Ads | Free app, attention sold to ad networks. The free-game economy | No cut on ad revenue |
| Storefront for physical goods/services | The takeaway model: app is free, money changes hands for real-world things via your own payment processor | No |
Subscriptions dominate because recurring revenue beats one-offs and the store cut softens in year two. The physical-goods carve-out is why food, rides, and retail apps happily live in the stores while content sellers often push purchases to the web.
7. Where to go deeper
Natural next topics, in rough order of how directly they build on this lesson:
- A login flow end to end: what actually happens, request by request, from tapping "log in with Google" to an authenticated session. Deep OAuth territory.
- Push notifications in detail: the full backend → FCM/APNs → device path, token management, and delivery guarantees. The most API-flavoured piece of mobile.
- Cross-platform frameworks compared: Flutter vs React Native vs Kotlin Multiplatform, and how teams choose.
- Building a small app as a Python developer: tooling, emulators, and a realistic learning path (most web developers find Flutter the gentlest on-ramp).
Check your understanding
- Why can one backend serve the website, both native apps, and a Python script without changing anything?
- Which three API features do offline-capable, aggressively-retrying mobile clients push you towards?
- Why must an API behind a mobile app stay backwards-compatible longer than one behind a website?
Reviewed 4 August 2026.