UniBase is a web service for storing and retrieving data. It supports various data manipulation operations including data storage, retrieval, update, deletion, and table management.
UniBase is built following the principles of Clean Architecture, which promotes separation of concerns and independent layers. This design ensures the system is scalable, maintainable, and testable.
-
Frameworks & Drivers: Handles the HTTP server setup and request routing. The server receives requests and delegates them to the controllers for further processing.
-
Interface Adapters: Contains the controllers and repositories. The controllers adapt the HTTP requests into method calls for the use cases, while the repositories handle interactions with the data layer (in this case, the file system).
-
Use Cases: Implements the application's business logic. Each use case corresponds to a specific business operation (e.g., storing data, retrieving data). Use cases interact with repositories to perform necessary data operations.
-
Entities: Contains the core business entities, which encapsulate the data structure used within the application.
When a request is made to UniBase, it passes through the following layers:
-
HTTP Request: The client sends an HTTP request to the UniBase server.
-
Server (Frameworks & Drivers Layer): The Node.js server receives the request and passes it to the
HttpController
. -
HttpController (Interface Adapters Layer): The controller identifies the type of request and forwards it to the appropriate use case.
-
Use Cases Layer: The use case class handles the business logic and coordinates operations, such as storing or retrieving data. It interacts with the
DataRepository
to access and manipulate data. -
DataRepository (Interface Adapters Layer): The repository manages the interaction with the file system, using the
FileManager
to perform read/write operations. -
FileManager (Interface Adapters Layer): The file manager performs the actual file I/O operations, reading from or writing to JSON files that represent tables.
-
HTTP Response: The result of the use case execution is returned through the
HttpController
back to the client.
- The service must accept requests containing a table name and JSON data.
- For each table name, a corresponding file must be created to store the data.
- If a new message comes with the same table name, the data must be appended to the existing file.
- The service must return an
entry_id
for the newly added data.
UniBase must support retrieval of data by table name:
- Retrieve all entries.
- Retrieve data by
entry_id
. - Retrieve data by searching any of the fields.
UniBase must support:
- Updating rows in a table by
entry_id
. - Deleting rows in a table by
entry_id
. - Deletion of an entire table by table name.
- UniBase should handle multiple requests concurrently.
- UniBase should be optimized for fast data retrieval and manipulation.
- UniBase should be designed to scale horizontally to handle increased load.
- UniBase should validate incoming data to prevent injection attacks.
- UniBase should ensure that data retrieval, update, and deletion operations are authenticated.
- UniBase should ensure data integrity during storage and retrieval operations.
- UniBase should handle file I/O errors gracefully and provide meaningful error messages.
- The API should have clear and consistent endpoints for storing, retrieving, updating, and deleting data.
- The API should provide meaningful responses for success and error cases.
- Endpoint:
POST /data/store
- Request Body:
{ "table_name": "string", "data": { ...json... } }
- Response:
{ "entry_id": "string" }
- Endpoint:
GET /data/{table_name}/all
- Response:
{ "data": [ ... ] }
- Endpoint:
GET /data/{table_name}/entry/{entry_id}
- Response:
{ "data": { ...json... } }
- Endpoint:
PUT /data/{table_name}/update/{entry_id}
- Request Body:
{ "data": { ...json... } }
- Response:
{ "status": "success" }
- Endpoint:
DELETE /data/{table_name}/delete/{entry_id}
- Response:
{ "status": "success" }
- Endpoint:
DELETE /data/{table_name}/delete
- Response:
{ "status": "success" }
- Each table should be stored in a separate file, e.g.,
table_name.json
. - The file should contain an array of JSON objects, each representing a row of data.
- Each row of data should be assigned a unique
entry_id
upon insertion. - The
entry_id
should be returned in the response to the insertion request.
- Return a 400 error if the table name is invalid.
- Return a 400 error if the JSON data is malformed.
- Return a 404 error if the specified table does not exist.
- Return a 404 error if the specified
entry_id
does not exist in the table.
- Return a 500 error for any unhandled server errors.
- Log all incoming requests with timestamps and request details.
- Log all errors with detailed error messages and stack traces.
- Implement monitoring to track service performance and availability.
- Provide detailed API documentation with examples for each endpoint.
- Include information on request and response formats, error codes, and usage scenarios.
Below is a sequence diagram that illustrates the request flow in UniBase:
@startuml
actor Client
Client -> Server: HTTP Request (POST /data/store)
Server -> HttpController: handleRequest(req, res)
alt Path: POST /data/store
HttpController -> StoreDataUseCase: execute(req, res)
StoreDataUseCase -> DataRepository: storeData(table_name, data)
DataRepository -> FileManager: getTableFilePath(tableName)
DataRepository -> FileManager: readFile(filePath)
FileManager --> DataRepository: tableData
DataRepository -> Entry: new Entry(data)
DataRepository -> FileManager: writeFile(filePath, tableData)
FileManager --> DataRepository: (write success)
DataRepository --> StoreDataUseCase: entry_id
StoreDataUseCase --> HttpController: entry_id
HttpController -> Client: HTTP Response (200 OK, entry_id)
else Invalid Path
HttpController -> Client: HTTP Response (404 Not Found)
end
note right of Server
Layer: Frameworks & Drivers
end note
note right of HttpController
Layer: Interface Adapters
end note
note right of StoreDataUseCase
Layer: Use Cases
end note
note right of DataRepository
Layer: Interface Adapters (Repository)
end note
note right of FileManager
Layer: Interface Adapters (File System)
end note
note right of Entry
Layer: Entities
end note
@enduml
Thanks for your interest in contributing to this project. Get started with our Contributing Guide.
- Augusto Salazar