|
1 | | -# ADR 0002: Use FastAPI for Backend |
| 1 | +# 2. Use FastAPI for Backend |
| 2 | + |
| 3 | +Date: 2026-01-02 |
2 | 4 |
|
3 | 5 | ## Status |
4 | 6 |
|
5 | 7 | Accepted |
6 | 8 |
|
7 | 9 | ## Context |
8 | 10 |
|
9 | | -We need a backend framework to: |
10 | | -- Serve REST API endpoints |
11 | | -- Integrate with EHRBase (HTTP client) |
12 | | -- Integrate with PostgreSQL (Prisma) |
13 | | -- Handle async operations efficiently |
| 11 | +We need a backend framework to serve REST API endpoints, integrate with EHRBase via HTTP, integrate with PostgreSQL through Prisma, and handle async operations efficiently. |
14 | 12 |
|
15 | | -Options considered: |
16 | | -1. **FastAPI** (Python) - Modern async Python framework |
17 | | -2. **Express/Fastify** (Node.js) - JavaScript/TypeScript backend |
18 | | -3. **Django** (Python) - Full-featured Python framework |
19 | | -4. **Go** - High-performance compiled language |
| 13 | +Four approaches were considered. FastAPI is a modern Python framework with first-class async/await support and automatic OpenAPI documentation. Express or Fastify on Node.js would provide JavaScript/TypeScript consistency with the frontend and excellent async patterns. Django offers a full-featured Python framework with an extensive ecosystem and built-in admin interface. Go would provide high performance and strong typing through a compiled language. |
20 | 14 |
|
21 | | -## Decision |
| 15 | +The backend will primarily perform I/O-bound operations: making HTTP requests to EHRBase, executing database queries, and serving JSON responses. These operations benefit more from efficient async handling than raw CPU performance. The team values type safety for catching errors early, automatic API documentation for development velocity, and a gentle learning curve that allows focus on openEHR concepts rather than framework complexity. |
22 | 16 |
|
23 | | -We will use **FastAPI** with **Python 3.11+**. |
| 17 | +## Decision |
24 | 18 |
|
25 | | -## Rationale |
| 19 | +We will use FastAPI with Python 3.11 or later as the backend framework. |
26 | 20 |
|
27 | | -- **Async-first**: Native async/await support, important for I/O-bound operations (HTTP to EHRBase, database queries) |
28 | | -- **Type hints**: First-class Pydantic integration for request/response validation |
29 | | -- **OpenAPI**: Automatic API documentation generation |
30 | | -- **Learning curve**: Python is accessible, FastAPI is well-documented |
31 | | -- **Ecosystem**: Good libraries for HTTP (httpx), database (Prisma), testing (pytest) |
| 21 | +We will use httpx as the async HTTP client for communicating with EHRBase, prisma-client-py for database access, pydantic-settings for configuration management, and pytest-asyncio for testing. All application code will use Python's native async/await syntax, and we will leverage Pydantic models throughout the service and API layers for consistent type validation. |
32 | 22 |
|
33 | 23 | ## Consequences |
34 | 24 |
|
35 | | -### Positive |
36 | | -- Clean async code with httpx for EHRBase communication |
37 | | -- Automatic request validation and documentation |
38 | | -- Pydantic models shared between API and service layers |
39 | | - |
40 | | -### Negative |
41 | | -- Python type system less strict than TypeScript or Go |
42 | | -- Need virtual environment management |
43 | | -- Slightly more complex deployment than Node.js |
44 | | - |
45 | | -### Technical Decisions |
46 | | -- Use `httpx` for async HTTP client (EHRBase) |
47 | | -- Use `prisma-client-py` for database access |
48 | | -- Use `pydantic-settings` for configuration |
49 | | -- Use `pytest-asyncio` for testing |
| 25 | +FastAPI's async-first architecture allows us to write clean, readable code for concurrent I/O operations without blocking threads or managing callback chains. The automatic request validation and OpenAPI documentation generation means we spend less time writing boilerplate validation code and manually maintaining API specifications. Pydantic models can be shared between API endpoints and service layers, ensuring type consistency throughout the application. |
| 26 | + |
| 27 | +However, Python's type system is less strict than TypeScript or Go, relying on optional static analysis with mypy rather than compile-time guarantees. We will need to manage Python virtual environments for dependency isolation, adding a step to the development setup compared to Node.js or Go. Deployment is slightly more complex than Node.js containerized applications, as we must ensure the correct Python runtime and activate virtual environments appropriately. |
| 28 | + |
| 29 | +The learning curve for FastAPI and async Python is accessible enough that developers can become productive quickly, allowing the team to focus energy on understanding openEHR rather than fighting the framework. |
0 commit comments