Pattern: Generic Data Endpoint & Registries
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.
The Challenge: Avoiding Boilerplate
Section titled “The Challenge: Avoiding Boilerplate”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.
The Solution: A Single Endpoint with Registries
Section titled “The Solution: A Single Endpoint with Registries”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.
GET /api/v1/data?model=headline
-> Returns a list of headlines.POST /api/v1/data?model=source
-> Creates a new source.
This is made possible by two key components:
-
ModelRegistry
: This registry maps a model name (e.g.,"headline"
) to aModelConfig
object. The config defines the rules for the model, such as authorization requirements and type-specific functions (fromJson
,getOwnerId
). -
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).
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.