03 / Backend Engineering
Fieldscript API
Backend API Engineering
A production-style FastAPI backend designed around strict contracts, predictable failures, and traceable request behavior.
01 / Problem
APIs usually fail at the edges.
A backend can appear correct when every request is valid, small, authenticated, and perfectly formed. Production behavior becomes harder when requests exceed payload limits, contain invalid data, reference the wrong project, fail authentication, hit rate limits, request missing resources, or trigger internal errors.
Fieldscript was built around making those cases explicit and predictable.
02 / API Contract
Predictable behavior is part of the interface.
Fieldscript defines consistent behavior around structured error responses, request IDs, explicit status codes, project-scoped resources, and validation boundaries. Error paths carry request-level traceability where implemented, so a failure remains connected to the request that produced it.
{
"error_code": "PAYLOAD_TOO_LARGE",
"message": "Total image payload exceeds allowed size",
"request_id": "..."
}Request-level traceability is returned in the body and response header.
03 / Request Lifecycle
Middleware and contract handling surround endpoint logic.
Cross-cutting behavior
04 / Payload Boundaries
Validate the real payload, not its encoding.
The OCR endpoint accepts base64 image payloads and enforces limits using estimated decoded byte size rather than raw base64 string length. This per-image and total decoded-size validation avoids unnecessary decoding just to enforce the boundary.
- Decoded-size limits per image
- Decoded-size limit across the request
- Explicit 413 response
- PAYLOAD_TOO_LARGE error code
- Request ID in response body
- Request ID in response header
05 / Asynchronous OCR
Longer work becomes a job, not a blocked request.
POST /v1/projects/{project_id}/ocr validates project scope and payload size, creates a unique job ID, stores a pending job, schedules OCR work with FastAPI BackgroundTasks, and returns HTTP 202. A polling route exposes the state and returns the result only after completion.
GET /v1/projects/{project_id}/jobs/{job_id}
The current job store is application-level and in-process. This is explicit asynchronous request handling and job-state modeling, not a claim of a distributed queue or durable external job system. The polling route also verifies that the job belongs to the requested project.
06 / Project Scope
Resources stay inside their project boundary.
Project-scoped routes use the path project ID as a boundary. The application rejects mismatches where an optional project ID header conflicts with the route project, and OCR jobs are checked against project ownership before results are returned.
Explicit scope checks keep one project context from accidentally retrieving another project's job state.
07 / API-Key Lifecycle
Authentication includes lifecycle, not just validation.
The project-scoped API-key routes support creating, listing, and revoking keys through dependency-based authentication. Stored public metadata can include a key prefix, name, creation time, last-used time, and revoked time where available.
/api/projects/{project_id}/api-keys
08 / Error Normalization
Failure should still follow the contract.
Explicit handlers cover request validation errors, FastAPI HTTP exceptions, and unhandled exceptions. The application normalizes failures into an error_code, message, and request_id shape, preserving HTTPException response headers where needed.
Unhandled errors are logged with traceback context while the client receives a controlled response without internal exception details.
09 / Request Traceability
Every request needs a thread to follow.
Request-ID middleware stores an identifier in request context, returns it through the x-request-id response header, and includes it in structured errors. Request logging and request-context middleware make that identifier available across the request lifecycle.
Traceability is designed into the request contract rather than added only after something fails.
10 / Middleware
Operational controls belong at the boundary.
The FastAPI application includes middleware for request IDs, request logging, request context, rate limiting, CORS, and security headers. It also exposes health and version routes, with development-only debug behavior kept separate from the normal request path.
11 / Persistence
Persistence is treated as schema, not an implementation detail.
SQLAlchemy database infrastructure, session management, models, and API-key storage are paired with Alembic configuration and migrations. Database evolution is versioned rather than left to manual schema changes.
12 / Testing
Edge cases are part of the specification.
The visible test suite covers API keys, database API-key smoke behavior, health, OCR jobs, and request logging. Repository documentation also describes contract testing around payload limits, boundary behavior, and request consistency.
Tests verify externally observable API contracts, not only internal implementation details. Boundary behavior is treated as part of the API specification.
13 / Containerization
Runtime assumptions stay explicit.
A Dockerfile, docker-compose.yml, dependency files, and a local Uvicorn development path keep containerized and deployment-oriented runtime assumptions visible without introducing claims about cloud orchestration.
14 / Architecture
Contract handling surrounds the service layer.
OCR request path
Persistence path
Cross-cutting controls
15 / Engineering Principle
Correctness includes the failure path.
Fieldscript demonstrates backend engineering where reliability is defined not only by successful requests, but by how consistently the system handles malformed, oversized, unauthorized, mismatched, missing, and failing requests.
Predictable failure is a feature of a reliable API.
16 / Technology
A backend stack built around explicit boundaries.
- Python
- FastAPI
- Pydantic
- SQLAlchemy
- Alembic
- pytest
- Docker