You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This file covers backend/API patterns SPECIFIC to mobile clients.
Generic backend patterns are in nodejs-best-practices and api-patterns.
Mobile backend is NOT the same as web backend. Different constraints, different patterns.
🧠 MOBILE BACKEND MINDSET
Mobile clients are DIFFERENT from web clients:
├── Unreliable network (2G, subway, elevator)
├── Battery constraints (minimize wake-ups)
├── Limited storage (can't cache everything)
├── Interrupted sessions (calls, notifications)
├── Diverse devices (old phones to flagships)
└── Binary updates are slow (App Store review)
Your backend must compensate for ALL of these.
🚫 AI MOBILE BACKEND ANTI-PATTERNS
These are common AI mistakes when building mobile backends:
TOKEN LIFECYCLE:
├── App registers → Get token → Send to backend
├── Token can change → App must re-register on start
├── Token expires → Clean from database
├── User uninstalls → Token becomes invalid (detect via error)
└── Multiple devices → Store multiple tokens per user
2. Offline Sync & Conflict Resolution
Sync Strategy Selection
WHAT TYPE OF DATA?
│
├── Read-only (news, catalog)
│ └── Simple cache + TTL
│ └── ETag/Last-Modified for invalidation
│
├── User-owned (notes, todos)
│ └── Last-write-wins (simple)
│ └── Or timestamp-based merge
│
├── Collaborative (shared docs)
│ └── CRDT or OT required
│ └── Consider Firebase/Supabase
│
└── Critical (payments, inventory)
└── Server is source of truth
└── Optimistic UI + server confirmation
Conflict Resolution Strategies
Strategy
How It Works
Best For
Last-write-wins
Latest timestamp overwrites
Simple data, single user
Server-wins
Server always authoritative
Critical transactions
Client-wins
Offline changes prioritized
Offline-heavy apps
Merge
Combine changes field-by-field
Documents, rich content
CRDT
Mathematically conflict-free
Real-time collaboration
Sync Queue Pattern
CLIENT SIDE:
├── User makes change → Write to local DB
├── Add to sync queue → { action, data, timestamp, retries }
├── Network available → Process queue FIFO
├── Success → Remove from queue
├── Failure → Retry with backoff (max 5 retries)
└── Conflict → Apply resolution strategy
SERVER SIDE:
├── Accept change with client timestamp
├── Compare with server version
├── Apply conflict resolution
├── Return merged state
└── Client updates local with server response
3. Mobile API Optimization
Response Size Reduction
Technique
Savings
Implementation
Field selection
30-70%
?fields=id,name,thumbnail
Compression
60-80%
gzip/brotli (automatic)
Pagination
Varies
Cursor-based for mobile
Image variants
50-90%
/image?w=200&q=80
Delta sync
80-95%
Only changed records since timestamp
Pagination: Cursor vs Offset
OFFSET (Bad for mobile):
├── Page 1: OFFSET 0 LIMIT 20
├── Page 2: OFFSET 20 LIMIT 20
├── Problem: New item added → duplicates!
└── Problem: Large offset = slow query
CURSOR (Good for mobile):
├── First: ?limit=20
├── Next: ?limit=20&after=cursor_abc123
├── Cursor = encoded (id + sort values)
├── No duplicates on data changes
└── Consistent performance
CLIENT VERSION vs MINIMUM VERSION:
├── client >= minimum → Continue normally
├── client < minimum → Show force update screen
│ └── Block app usage until updated
└── client < latest → Show optional update prompt
FEATURE FLAGS:
├── Enable/disable features without app update
├── A/B testing by version/device
└── Gradual rollout (10% → 50% → 100%)
5. Authentication for Mobile
Token Strategy
ACCESS TOKEN:
├── Short-lived (15 min - 1 hour)
├── Stored in memory (not persistent)
├── Used for API requests
└── Refresh when expired
REFRESH TOKEN:
├── Long-lived (30-90 days)
├── Stored in SecureStore/Keychain
├── Used only to get new access token
└── Rotate on each use (security)
DEVICE TOKEN:
├── Identifies this device
├── Allows "log out all devices"
├── Stored alongside refresh token
└── Server tracks active devices
Silent Re-authentication
REQUEST FLOW:
├── Make request with access token
├── 401 Unauthorized?
│ ├── Have refresh token?
│ │ ├── Yes → Call /auth/refresh
│ │ │ ├── Success → Retry original request
│ │ │ └── Failure → Force logout
│ │ └── No → Force logout
│ └── Token just expired (not invalid)
│ └── Auto-refresh, user doesn't notice
└── Success → Continue
6. Error Handling for Mobile
Mobile-Specific Error Format
{
"error": {
"code": "PAYMENT_DECLINED",
"message": "Your payment was declined",
"user_message": "Please check your card details or try another payment method",
"action": {
"type": "navigate",
"destination": "payment_methods"
},
"retry": {
"allowed": true,
"after_seconds": 5
}
}
}
Error Categories
Code Range
Category
Mobile Handling
400-499
Client error
Show message, user action needed
401
Auth expired
Silent refresh or re-login
403
Forbidden
Show upgrade/permission screen
404
Not found
Remove from local cache
409
Conflict
Show sync conflict UI
429
Rate limit
Retry after header, backoff
500-599
Server error
Retry with backoff, show "try later"
Network
No connection
Use cached data, queue for sync
7. Media & Binary Handling
Image Optimization
CLIENT REQUEST:
GET /images/{id}?w=400&h=300&q=80&format=webp
SERVER RESPONSE:
├── Resize on-the-fly OR use CDN
├── WebP for Android (smaller)
├── HEIC for iOS 14+ (if supported)
├── JPEG fallback
└── Cache-Control: max-age=31536000
Chunked Upload (Large Files)
UPLOAD FLOW:
1. POST /uploads/init
{ filename, size, mime_type }
→ { upload_id, chunk_size }
2. PUT /uploads/{upload_id}/chunks/{n}
→ Upload each chunk (1-5 MB)
→ Can resume if interrupted
3. POST /uploads/{upload_id}/complete
→ Server assembles chunks
→ Return final file URL
Streaming Audio/Video
REQUIREMENTS:
├── HLS (HTTP Live Streaming) for iOS
├── DASH or HLS for Android
├── Multiple quality levels (adaptive bitrate)
├── Range request support (seeking)
└── Offline download chunks
ENDPOINTS:
GET /media/{id}/manifest.m3u8 → HLS manifest
GET /media/{id}/segment_{n}.ts → Video segment
GET /media/{id}/download → Full file for offline
8. Security for Mobile
Device Attestation
VERIFY REAL DEVICE (not emulator/bot):
├── iOS: DeviceCheck API
│ └── Server verifies with Apple
├── Android: Play Integrity API (replaces SafetyNet)
│ └── Server verifies with Google
└── Fail closed: Reject if attestation fails
MOBILE-SPECIFIC LIMITS:
├── Per device (X-Device-ID)
├── Per user (after auth)
├── Per endpoint (stricter for sensitive)
└── Sliding window preferred
HEADERS:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1609459200
Retry-After: 60 (when 429)
9. Monitoring & Analytics
Required Headers from Mobile
Every mobile request should include:
├── X-App-Version: 2.1.0
├── X-Platform: ios | android
├── X-OS-Version: 17.0
├── X-Device-Model: iPhone15,2
├── X-Device-ID: uuid (persistent)
├── X-Request-ID: uuid (per request, for tracing)
├── Accept-Language: tr-TR
└── X-Timezone: Europe/Istanbul
What to Log
FOR EACH REQUEST:
├── All headers above
├── Endpoint, method, status
├── Response time
├── Error details (if any)
└── User ID (if authenticated)
ALERTS:
├── Error rate > 5% per version
├── P95 latency > 2 seconds
├── Specific version crash spike
├── Auth failure spike (attack?)
└── Push delivery failure spike
📝 MOBILE BACKEND CHECKLIST
Before API Design
Identified mobile-specific requirements?
Planned offline behavior?
Designed sync strategy?
Considered bandwidth constraints?
For Every Endpoint
Response as small as possible?
Pagination cursor-based?
Proper caching headers?
Mobile error format with actions?
Authentication
Token refresh implemented?
Silent re-auth flow?
Multi-device logout?
Secure token storage guidance?
Push Notifications
FCM + APNs configured?
Token lifecycle managed?
Silent vs display push defined?
Sensitive data NOT in push payload?
Release
Version check endpoint ready?
Feature flags configured?
Force update mechanism?
Monitoring headers required?
Remember: Mobile backend must be resilient to bad networks, respect battery life, and handle interrupted sessions gracefully. The client cannot be trusted, but it also cannot be hung up—provide offline capabilities and clear error recovery paths.