161 lines
4.1 KiB
Markdown
161 lines
4.1 KiB
Markdown
|
||
# Backend API – Getting Started
|
||
|
||
## 1. Project overview
|
||
|
||
The `backend-api` is a small REST API responsible for receiving, storing and delivering notifications.
|
||
|
||
It uses:
|
||
- **FastAPI:** Python web framework for building REST APIs.
|
||
- **Uvicorn:** Server used to run the FastAPI application.
|
||
- **SQLite:** Lightweight database for storing notifications.
|
||
- **Pydantic:** Data validation for incoming API requests (included with FastAPI).
|
||
|
||
## 2. API endpoints
|
||
|
||
The application requires two POST endpoints. POST is used when the application call changes something, GET when it just retrieves information.
|
||
|
||
| Method | Endpoint | Description |
|
||
|---|---|---|
|
||
| POST | `/notifications` | Receive and store a notification. |
|
||
| POST | `/notifications/deliver` | Retrieve pending notifications and mark them as delivered. |
|
||
|
||
### Receiving notifications
|
||
|
||
`POST /notifications`
|
||
|
||
Accepts a JSON payload containing the notification information.
|
||
|
||
Example request:
|
||
|
||
```json
|
||
{
|
||
"title": "New notification",
|
||
"body": "Something happened!",
|
||
"link": "https://example.com",
|
||
"timestamp": 1791626400
|
||
}
|
||
```
|
||
|
||
The API validates the payload and saves it into the `notifications` database.
|
||
|
||
Each notification should have a `delivered` flag, initially set to `false`.
|
||
|
||
### Getting notifications
|
||
|
||
`POST /notifications/deliver`
|
||
|
||
This endpoint retrieves all notifications where `delivered = false`.
|
||
|
||
The application should:
|
||
1. Query the database for undelivered notifications.
|
||
2. Set their `delivered` flag to `true`.
|
||
3. Commit the database transaction.
|
||
4. Return the retrieved notifications as JSON.
|
||
|
||
Example response:
|
||
|
||
```json
|
||
[
|
||
{
|
||
"id": 1,
|
||
"title": "New notification",
|
||
"body": "Something happened!",
|
||
"link": "https://example.com",
|
||
"timestamp": 1791626400,
|
||
"delivered": true
|
||
}
|
||
]
|
||
```
|
||
|
||
If there are no pending notifications, return an empty array.
|
||
|
||
**Important:** The database update should happen before returning the notifications. This prevents the same notifications from being delivered again on subsequent requests.
|
||
|
||
## 3. Database structure
|
||
|
||
For the initial implementation, use SQLite.
|
||
|
||
The database will be stored in a local file called `notifications.db`.
|
||
|
||
The `notifications` table should contain:
|
||
|
||
| Column | Type | Description |
|
||
|---|---|---|
|
||
| `id` | INTEGER | Unique notification identifier (primary key). |
|
||
| `title` | TEXT | Notification title. |
|
||
| `body` | TEXT | Notification content. |
|
||
| `link` | TEXT | Optional URL associated with the notification. |
|
||
| `timestamp` | INTEGER | Unix timestamp of the notification. |
|
||
| `delivered` | BOOLEAN | Indicates whether the notification was delivered. |
|
||
|
||
---
|
||
|
||
# 4. Minimal working implementation
|
||
|
||
The following implementation gives you a baseline for starting the server
|
||
|
||
## requirements.txt
|
||
|
||
```text
|
||
fastapi
|
||
uvicorn
|
||
```
|
||
|
||
## src/main.py
|
||
|
||
```python
|
||
from contextlib import asynccontextmanager
|
||
from fastapi import FastAPI
|
||
from pydantic import BaseModel #use this to create the Notification class
|
||
from db_module import initialize_database, get_database #Implement these yourself with SqLite3
|
||
|
||
|
||
@asynccontextmanager
|
||
async def lifespan(app: FastAPI):
|
||
initialize_database()
|
||
yield
|
||
|
||
|
||
app = FastAPI(lifespan=lifespan)
|
||
|
||
@app.post("/notifications")
|
||
def receive_notification(notification: Notification):
|
||
|
||
|
||
|
||
@app.post("/notifications/deliver")
|
||
def deliver_notifications():
|
||
|
||
```
|
||
|
||
## 6. Run the application
|
||
|
||
Make sure the virtual environment is activated and the dependencies are installed.
|
||
|
||
Start the application from the project root:
|
||
|
||
```bash
|
||
uvicorn src.main:app --host 0.0.0.0 --port 8100 --reload
|
||
```
|
||
|
||
Explanation:
|
||
|
||
| Argument | Description |
|
||
|---|---|
|
||
| `src.main:app` | Imports the FastAPI instance called `app` from `src/main.py`. |
|
||
| `--host 0.0.0.0` | Makes the server accessible outside localhost. |
|
||
| `--port 8100` | Port on which the API listens. |
|
||
| `--reload` | Automatically restarts the server when source files change. |
|
||
|
||
The `--reload` option should only be used during development.
|
||
|
||
## 7. Test the application
|
||
|
||
FastAPI automatically generates interactive API documentation.
|
||
|
||
Open:
|
||
|
||
http://localhost:8100/docs
|
||
|
||
You can use the Swagger UI to execute both POST endpoints without installing additional tools. |