Mobile Backends

Flaxon is designed to be an excellent backend for mobile applications with JSON APIs, WebSocket support, and technology neutrality.

Android (Kotlin) Backend

from flaxon import Flaxon
from flaxon.validation import Schema, fields

app = Flaxon("android-backend")

class DeviceRegistration(Schema):
    device_id = fields.String(required=True, min_length=8)
    platform = fields.Choice(["android", "ios"], required=True)
    notification_token = fields.String(required=True, min_length=16)

@app.post("/api/v1/devices")
async def register_device(data: DeviceRegistration):
    return {"success": True, "device": data.to_dict()}

@app.post("/api/v1/auth/login")
async def login(request):
    data = await request.json()
    user = await auth_service.authenticate(data["email"], data["password"])
    token = await jwt_backend.create_token(user)
    return {"access_token": token, "user": user.to_dict()}

Real-Time Features (WebSocket)

@app.websocket("/ws/mobile")
async def mobile_websocket(socket: WebSocket):
    user = getattr(socket.scope, "user", None)
    if not user:
        await socket.close(code=4001)
        return

    await socket.accept()
    await socket.join(f"user_{user.id}")

    try:
        async for message in socket.iter_json():
            event = message.get("event")
            if event == "ping":
                await socket.send_json({"event": "pong"})
            elif event == "message":
                await handle_mobile_message(user, message["data"])
            elif event == "location":
                await update_user_location(user.id, message["data"])
    except WebSocketDisconnect:
        pass

Push Notifications (FCM)

import firebase_admin
from firebase_admin import messaging

firebase_admin.initialize_app()

@app.post("/api/v1/notifications/send")
async def send_notification(request):
    data = await request.json()
    user_id = data["user_id"]
    tokens = await device_service.get_tokens(user_id)

    for token in tokens:
        message = messaging.Message(
            notification=messaging.Notification(
                title=data["title"],
                body=data["message"],
            ),
            token=token,
        )
        await messaging.send_async(message)

    return {"sent": len(tokens)}

Offline-First Synchronization

@app.post("/api/v1/sync")
async def sync_data(request):
    data = await request.json()
    last_sync = data.get("last_sync", 0)

    changes = {
        "users": await user_service.get_changes_since(last_sync),
        "posts": await post_service.get_changes_since(last_sync),
    }

    if data.get("local_changes"):
        await process_local_changes(data["local_changes"])

    return {"server_time": time.time(), "changes": changes}

File Uploads

from flaxon.files import FileUpload, FileStorage

upload_handler = FileUpload(max_size=50 * 1024 * 1024)
storage = FileStorage("uploads")

@app.post("/api/v1/upload")
async def upload_file(request):
    files = await upload_handler.parse(request)
    uploaded = []

    for file in files:
        path = storage.save(file)
        uploaded.append({
            "filename": file.filename,
            "url": storage.get_url(path),
            "size": file.size,
        })

    return {"files": uploaded}
Best Practices
  • Use JWT with short expiration (15-30 minutes)
  • Implement refresh token rotation
  • Use pagination for all list endpoints
  • Support offline-first synchronization
  • Use chunked uploads for large files