Skip to content

Build custom collection dispatcher example and tutorial (Hono + Deno) #694

@dahlia

Description

@dahlia

Sub-issue of #99. Deliver the custom collection dispatcher scenario as a paired example repository and fedify.dev tutorial, as set in #99 (comment).

This also gives us a single place to point at when users ask about Federation.setXxxDispatcher() patterns. The question has come up repeatedly in issues and on Discord without a canonical answer, and a focused worked example is more useful than scattered snippets.

Scenario

A personal federated bookmark log. A single user collects links, tags them, and exposes several distinct ActivityPub collections on their actor. The didactic centerpiece is the custom collection dispatcher: how to expose arbitrary server-side data as a paginated, filtered, and access-controlled ActivityPub collection.

The application is intentionally small so the dispatchers, not the surrounding code, are the focus. The same patterns generalise to any service that exposes reading lists, curated indexes, or domain-specific feeds.

Stack

  • Framework: Hono
  • Integration package: @fedify/hono
  • Runtime: Deno
  • Storage: node:sqlite (via Deno's Node.js compatibility), no ORM
  • Database: SQLite

Feature checklist

  • Single-owner actor (Person) with WebFinger, persisted key pair, and a minimal HTML profile view.
  • Bookmark management (owner-only HTTP auth): add a link with title, URL, tags, optional note, and visibility (public or followers-only). Edit and delete.
  • Per-bookmark public HTML page with a stable canonical URL.
  • Three custom collections on the actor, each exercising one of the patterns called out in More examples #99: pagination, filtering, and authorization.
    1. Public bookmarks (/collections/public): anonymous-accessible paginated OrderedCollection. Demonstrates basic pagination with setCounter and cursor-based paging.
    2. Tagged bookmarks (/collections/tag/{tag}): parameterised dispatcher filtering on a URL segment. Demonstrates dynamic URL bindings and filtered queries inside a dispatcher.
    3. Followers-only bookmarks (/collections/followers-only): contents depend on the requester. Verifies the requesting actor via HTTP Signatures, confirms they follow the owner, and returns an empty collection for non-followers. Demonstrates authorization from inside a dispatcher.
  • Outbound federation: Create(Note) on a new public bookmark, Update(Note) on edit, Delete(Note) on removal. Followers-only bookmarks federate only to verified followers.
  • Inbox handlers: Follow (auto-accept), Undo(Follow). Minimal reception handling, kept deliberately thin so the collection dispatcher patterns stay front and center.

Deliverables

  1. Create fedify-dev/hono-bookmarks under the fedify-dev org. Full runnable Hono app on Deno implementing the feature checklist above.
  2. Write docs/tutorial/custom-collections.md on fedify.dev as a step-by-step walkthrough. The tutorial should cover @fedify/hono setup on Deno, each of the three collection patterns, how to wire setCounter and cursor-based pagination, and how to perform requester-identity authorization inside a dispatcher.
  3. Add the new tutorial to TUTORIAL.items in docs/.vitepress/config.mts.
  4. README of fedify-dev/hono-bookmarks links back to the tutorial.
  5. Tutorial cross-links the Deno section of the Deployment docs (Best practices for production deployments #689) and the @fedify/hono integration docs.
  6. Close the loop on prior community questions: in a final Further reading section, link to the tutorial from the pre-existing issues and discussion threads that motivated it.
  7. Add an entry to CHANGES.md.

Out of scope

  • Multi-user signup and per-user actors. Single-owner keeps the focus on collection dispatch patterns.
  • Rich UI, themes, full-text search across bookmarks.
  • Likes, boosts, replies. Covered by sibling sub-issues; omitted here so the dispatcher patterns remain the unambiguous focus.
  • ORM-based variant. First-pass stack is intentionally raw node:sqlite.
  • Import/export from existing bookmark services (Pinboard, Raindrop, etc.). A useful follow-up but not core to the collection dispatcher learning.

Metadata

Metadata

Assignees

Labels

Type

Projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions