Layered Architecture Components
The diagram illustrates the layered architecture of the Pagemark API, showing how requests flow from the external API layer down to the data persistence layer.
- API Layer: app.routes contains Flask Blueprints (bookmarks, tags, collections) that handle incoming HTTP requests. These routes do not contain business logic; instead, they delegate all operations to the service layer.
- Service Layer: The app.services.bookmark_service (implemented as a
BookmarkServicesingleton) acts as the central orchestrator. It manages validation, cache invalidation, and coordinates between the repository and the search index. - Search & Cache: The app.services.search_service (
SearchIndex) provides full-text search capabilities by maintaining an inverted index of bookmark content. The app.services._cache (LRUCache) provides an internal, fixed-size cache to speed up bookmark retrieval. - Data Layer: The app.db.repository (
BookmarkRepository) provides an in-memory abstraction for data storage, isolating the rest of the application from the underlying storage mechanism. - Domain Layer: app.models.bookmark and other models define the core data structures used across all layers of the application.
The flow typically starts with a user request to a route, which calls a method on the BookmarkService. The service then interacts with the cache, repository, and search index as needed to fulfill the request, using domain models to pass data between components.
Key Architectural Findings:
- BookmarkService is a singleton facade that orchestrates all business logic and cross-component operations.
- The architecture follows a strict layered pattern where routes delegate to services, and services interact with repositories.
- SearchIndex maintains an inverted index and depends on the BookmarkRepository to fetch full bookmark objects during search.
- LRUCache is an internal component of the service layer used specifically for bookmark retrieval performance.
- The BookmarkRepository implements an in-memory data access pattern, providing a clean boundary for future database integration.