Skip to main content

Getting Started with Bookmark Management

This tutorial walks you through using the BookmarkService in etchblok-test-api to manage your bookmarks. You will learn how to initialize the service, create a validated bookmark, and retrieve it for display.

Prerequisites

To follow this tutorial, ensure your environment is set up and you can import the app package. The BookmarkService automatically initializes its own dependencies, including the BookmarkRepository and SearchIndex.

Step 1: Initialize the BookmarkService

The BookmarkService is implemented as a singleton. This ensures that stateful components, like the internal LRU cache, are shared across your entire application (e.g., between different Flask blueprints).

from app.services.bookmark_service import BookmarkService

# Calling the constructor always returns the same instance
service = BookmarkService()

Step 2: Create a Validated Bookmark

To create a bookmark, pass a dictionary containing at least a url and a title to the create_bookmark method. The service performs validation using internal rules defined in app.models._validators.

The method returns a tuple: (Bookmark, None) on success, or (None, error_message) on failure.

bookmark_data = {
"url": "https://github.com/example/project",
"title": "Example Project",
"description": "A very useful repository for testing."
}

bookmark, error = service.create_bookmark(bookmark_data)

if error:
print(f"Failed to create bookmark: {error}")
else:
print(f"Created bookmark with ID: {bookmark.id}")

In etchblok-test-api, validation fails if:

  • The url does not match the standard HTTP/HTTPS pattern.
  • The title is missing or exceeds 256 characters.

Step 3: Retrieve a Bookmark

Once a bookmark is created, you can retrieve it using its unique ID. The BookmarkService first checks its internal LRUCache before querying the BookmarkRepository.

bookmark_id = bookmark.id  # From the previous step
retrieved = service.get_bookmark(bookmark_id)

if retrieved:
print(f"Found: {retrieved.title} ({retrieved.url})")

Step 4: Serialize for API Responses

The Bookmark object returned by the service is a domain model. To convert it into a format suitable for a JSON response, use the to_dict() method.

import json

if retrieved:
# Convert the Bookmark model to a dictionary
data = retrieved.to_dict()
print(json.dumps(data, indent=2))

The resulting dictionary includes the bookmark's id, status (e.g., "active"), and timestamps:

{
"id": "a1b2c3d4e5f6",
"url": "https://github.com/example/project",
"title": "Example Project",
"description": "A very useful repository for testing.",
"tags": [],
"status": "active",
"created_at": "2023-10-27T10:00:00Z",
"updated_at": "2023-10-27T10:00:00Z",
"metadata": {}
}

Complete Example

Here is how these steps typically look when integrated into a route handler, similar to the implementation in app/routes/bookmarks.py:

from app.services.bookmark_service import BookmarkService

service = BookmarkService()

def add_new_resource(url, title):
payload = {"url": url, "title": title}

# 1. Create with validation
bookmark, error = service.create_bookmark(payload)

if error:
return {"error": error}, 400

# 2. Retrieve (demonstrating cache usage)
refreshed = service.get_bookmark(bookmark.id)

# 3. Return serialized data
return refreshed.to_dict(), 201

# Usage
result, status_code = add_new_resource("https://example.com", "Example")
print(f"Status {status_code}: {result}")

Next Steps