Mobile API Best Practices · Mobile Auth, Security & Flaky Networks
Media Uploads & Delivery
Direct-to-storage uploads, resumable transfers and image CDNs.
Don't stream large uploads through your API servers. Issue pre-signed URLs (S3/GCS/Azure) or use a resumable protocol (tus, GCS resumable, S3 multipart) so uploads survive network changes. Validate after upload (size, type sniffing, malware scan), then mark the media ready via a callback or event. For delivery, use an image CDN that resizes and converts (AVIF/WebP) per device, with long cache TTLs and content-hashed URLs.
Upload strategies
| Criterion | Through API server | Pre-signed single PUT | Resumable / multipart |
|---|---|---|---|
| Server load | High | None | None |
| Survives network drop | No | No (restart) | Yes (resume) |
| Large files (100MB+) | Poor | OK on good networks | Best |
| Validation | Inline | After upload (event) | After upload (event) |
| Complexity | Low | Low | Medium |
@router.post("/v1/uploads")
async def create_upload(body: UploadIn, user=Depends(current_user)):
if body.size > 50 * 1024 * 1024 or body.content_type not in ALLOWED:
raise ProblemError(422, "invalid-upload")
key = f"uploads/{user.id}/{uuid7()}"
url = s3.generate_presigned_url("put_object", ExpiresIn=900,
Params={"Bucket": BUCKET, "Key": key, "ContentType": body.content_type})
await media.create(key=key, owner=user.id, status="pending")
return {"upload_url": url, "media_id": key}
import { PutObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
const key = `uploads/${user.id}/${crypto.randomUUID()}`;
const url = await getSignedUrl(s3, new PutObjectCommand({ Bucket, Key: key, ContentType: body.contentType }), { expiresIn: 900 });
res.status(201).json({ upload_url: url, media_id: key });
Common pitfalls
- Trusting client-declared content type without server-side checks.
- Serving originals to every device.
- Upload URLs that never expire.
Key points
- Direct-to-storage, short-lived URLs
- Resumable for large files
- Image CDN for per-device variants
Further reading: tus resumable upload protocol
Practice questions
Why use pre-signed URLs for mobile uploads?
Answer
Clients upload directly to object storage, so API servers aren't tied up streaming bytes, and access is scoped and time-limited.
When should you use a resumable upload protocol?
Answer
For large files or unreliable networks, so an interrupted upload resumes from the last received byte instead of restarting.
Open in the app to mark lessons complete, take notes and track your progress.