Skip to content

Commit 80cbc4e

Browse files
committed
docs(api-server): update architecture explanation for generic data endpoint
- Rename to 'Pattern: Generic Data Endpoint & Registries' - Refactor content structure for better clarity - Introduce concept of two central registries: ModelRegistry and DataOperationRegistry - Simplify language and remove redundant information - Add reference to Architectural Deep Dive guide for more details
1 parent ab6514e commit 80cbc4e

File tree

1 file changed

+17
-31
lines changed

1 file changed

+17
-31
lines changed
Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,38 @@
11
---
2-
title: Generic Data Endpoint
3-
description: Understand the powerful generic data endpoint and model registry pattern used in the API server.
2+
title: 'Pattern: Generic Data Endpoint & Registries'
3+
description: Understand the powerful generic data endpoint and registry patterns used in the API server.
44
---
55

66
import { Aside } from '@astrojs/starlight/components';
77

8-
A significant architectural pattern in the API server is the use of a generic data endpoint powered by a `model_registry`. This design provides a single, consistent, and powerful interface for all standard CRUD (Create, Read, Update, Delete) operations, reducing code duplication and simplifying both the backend and client-side implementations.
8+
A significant architectural pattern in the API server is the use of a generic data endpoint powered by two central registries. This design provides a single, consistent, and powerful interface for all standard CRUD (Create, Read, Update, Delete) operations, reducing code duplication and simplifying both the backend and client-side implementations.
99

1010
### The Challenge: Avoiding Boilerplate
1111

12-
A typical REST API might have separate endpoints for each data type:
13-
- `/api/v1/headlines`
14-
- `/api/v1/topics`
15-
- `/api/v1/sources`
16-
- ...and so on.
12+
A typical REST API might have separate endpoints for each data type: `/headlines`, `/topics`, `/sources`, etc. This approach leads to a lot of boilerplate code, as the logic for handling GET, POST, PUT, and DELETE requests is often very similar for each model.
1713

18-
While clear, this approach leads to a lot of boilerplate code, as the logic for handling GET, POST, PUT, and DELETE requests is often very similar for each model.
14+
### The Solution: A Single Endpoint with Registries
1915

20-
### The Solution: A Single Endpoint with a Model Registry
21-
22-
This API server solves the problem by using a single, dynamic endpoint:
23-
24-
```
25-
/api/v1/data
26-
```
27-
28-
This endpoint handles requests for **all** standard data models. The specific model to be acted upon is determined by a `?model=` query parameter.
16+
This API server solves the problem by using a single, dynamic endpoint: `/api/v1/data`. This endpoint handles requests for all standard data models, with the specific model determined by a `?model=` query parameter.
2917

3018
- `GET /api/v1/data?model=headline` -> Returns a list of headlines.
31-
- `GET /api/v1/data/some-id?model=topic` -> Returns a single topic.
3219
- `POST /api/v1/data?model=source` -> Creates a new source.
3320

34-
### The `model_registry`
21+
This is made possible by two key components:
3522

36-
The magic behind this is the `model_registry`, a map defined in `lib/src/registry/model_registry.dart`. This registry links the string name of a model (e.g., "headline") to a `ModelConfig` object.
23+
1. **`ModelRegistry`**: This registry maps a model name (e.g., `"headline"`) to a `ModelConfig` object. The config defines the **rules** for the model, such as authorization requirements and type-specific functions (`fromJson`, `getOwnerId`).
3724

38-
Each `ModelConfig` contains:
39-
- **Type-Specific Functions:** Functions like `fromJson` to deserialize the data correctly.
40-
- **Authorization Rules:** A detailed permission configuration for each HTTP method (GET, POST, PUT, DELETE), specifying what roles or permissions are required for that action.
25+
2. **`DataOperationRegistry`**: This registry maps a model name to the actual **functions** that perform the CRUD operations (e.g., the function to fetch all headlines, the function to create a new source).
4126

42-
When a request comes in, the server's middleware looks up the `model` parameter in the registry, retrieves the correct configuration, and uses it to:
43-
1. Authorize the request based on the user's role and the action's permission requirements.
44-
2. Forward the request to the correct generic `DataRepository`.
45-
3. Deserialize and serialize data using the correct model class.
27+
When a request comes in, middleware uses the `ModelRegistry` to authorize the request and the route handlers use the `DataOperationRegistry` to execute the correct data operation.
4628

4729
<Aside type="note" title="Architectural Benefits">
48-
- **DRY (Don't Repeat Yourself):** Eliminates redundant route handlers for CRUD operations.
30+
- **DRY (Don't Repeat Yourself):** Eliminates redundant route handlers.
4931
- **Consistency:** Provides a uniform API for all data models.
50-
- **Extensibility:** Adding CRUD support for a new data model is as simple as adding a new entry to the `model_registry`.
51-
- **Centralized Authorization:** Security rules for data access are defined in one central, easy-to-audit location.
32+
- **Extensibility:** Adding CRUD support for a new model is as simple as adding entries to the two registries.
33+
- **Centralized Logic:** Authorization rules and data operations are defined in central, easy-to-audit locations.
34+
</Aside>
35+
36+
<Aside type="tip">
37+
For a complete, step-by-step walkthrough of how the endpoint, registries, and middleware work together, see the [**Architectural Deep Dive: Data Access Flow**](./data-access-flow) guide.
5238
</Aside>

0 commit comments

Comments
 (0)