Skip to content

Conversation

@2chanhaeng
Copy link
Contributor

Summary

This PR implements custom collection dispatchers for Fedify, allowing developers to create and expose arbitrary collections of ActivityPub objects beyond the built-in collections (outbox, inbox, following, followers, etc.). The feature supports both unordered collections and ordered collections with full pagination support.

Related Issue

Changes

  • Added CustomCollectionDispatcher, CustomCollectionCounter, and CustomCollectionCursor callback types for custom collection dispatching
  • Added CustomCollectionCallbackSetters interface for configuring custom collection callbacks (counter, first/last cursor, authorization)
  • Implemented setCollectionDispatcher() and setOrderedCollectionDispatcher() methods in the Federatable interface and FederationBuilderImpl class
  • Added getCollectionUri() method to the Context interface for constructing custom collection URIs
  • Created CustomCollectionHandler class with handleCustomCollection() and handleOrderedCollection() functions to process custom collection requests
  • Added utility types ConstructorWithTypeId and ParamsKeyPath for type-safe custom collection dispatchers
  • Implemented routing and middleware support for custom collections in FederationImpl
  • Added parsing support for custom collection URIs in Context.parseUri()
  • Updated testing utilities to support custom collections in createContext()
  • Added comprehensive test coverage for custom collection functionality

Benefits

  • Extensibility: Developers can now create custom collections for any type of ActivityPub objects (bookmarks, favorites, categories, etc.) without being limited to built-in collection types
  • Type Safety: Full TypeScript support with generic types ensures type-safe collection dispatchers and proper parameter validation
  • Consistency: Custom collections follow the same patterns and APIs as built-in collections, making them familiar and easy to use
  • Flexibility: Support for multiple URI parameters allows complex collection structures (e.g., /users/{id}/categories/{category}/posts)
  • Standard Compliance: Generated collections conform to ActivityPub collection specifications with proper pagination support
  • Performance: Cursor-based pagination support enables efficient traversal of large collections
  • Security: Built-in authorization support allows fine-grained access control for custom collections

Checklist

  • Did you add a changelog entry to the CHANGES.md?
  • Did you write some relevant docs about this change (if it's a new feature)?
  • Did you write a regression test to reproduce the bug (if it's a bug fix)?
  • Did you write some tests for this change (if it's a new feature)?
  • Did you run deno task test-all on your machine?

Additional Notes

This feature significantly extends Fedify's capabilities by allowing developers to expose any type of collection through the ActivityPub protocol. The implementation maintains backward compatibility and follows existing architectural patterns. The API design mirrors the built-in collection dispatchers for consistency and ease of adoption.

The custom collections support all the same features as built-in collections:

  • Cursor-based pagination
  • Item counting
  • Authorization predicates
  • Both Collection and OrderedCollection types
  • Multiple URL parameters
  • Proper ActivityPub JSON-LD context handling

Examples of potential use cases include user bookmarks, post categories, custom feeds, recommendation lists, and any other grouped content that applications might want to expose through ActivityPub.

2chanhaeng and others added 11 commits July 24, 2025 10:37
- [`CustomCollectionDispatcher`](./fedify/federation/callbacks.ts#CustomCollectionDispatcher)
- [`CustomCollectionCounter`](./fedify/federation/callbacks.ts#CustomCollectionCounter)
- [`CustomCollectionCursor`](./fedify/federation/callbacks.ts#CustomCollectionCounter)
- [`CustomCollectionCallbackSetters`](./fedify/federation/federation.ts#CustomCollectionCallbackSetters)
- [`Federatable`](./fedify/federation/federation.ts#Federatable)
  - [`setCollectionDispatcher`](./fedify/federation/federation.ts#Federatable.setCollectionDispatcher)
  - [`setOrderedCollectionDispatcher`](./fedify/federation/federation.ts#Federatable.setCollectionDispatcher)
- Some utility types for dispatchers
  - [`ConstructorWithTypeId`](./fedify/federation/federation.ts#ConstructorWithTypeId)
  - [`ParamsKeyPath`](./fedify/federation/federation.ts#ParamsKeyPath)
[`Context.getCollectionUri`](./fedify/federation/context.ts#Context.getCollectionUri)
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @2chanhaeng, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances Fedify's extensibility by introducing support for custom ActivityPub collections. Developers can now define and expose their own paginated collections of objects, moving beyond the standard built-in types like outbox or inbox. This feature provides a flexible and type-safe mechanism for creating rich, application-specific data feeds that adhere to ActivityPub specifications.

Highlights

  • Custom Collection Dispatchers: Introduced new API methods (setCollectionDispatcher, setOrderedCollectionDispatcher) to allow developers to register custom logic for serving arbitrary ActivityPub collections, supporting both unordered and ordered types.
  • Flexible URI Patterns: Custom collections can be defined with flexible URI patterns, including multiple parameters, enabling complex collection structures (e.g., /users/{id}/categories/{category}/posts).
  • Comprehensive Callback Support: Custom collections support the same callback mechanisms as built-in collections for pagination (first/last cursors), item counting, and fine-grained authorization.
  • Type Safety and Extensibility: New TypeScript types (CustomCollectionDispatcher, CustomCollectionCallbackSetters, ConstructorWithTypeId, ParamsKeyPath) ensure type-safe implementation and provide a robust framework for extending Fedify's collection capabilities.
  • Routing and Context Integration: Integrated custom collection handling into Fedify's routing system and Context interface, allowing for proper URI construction (getCollectionUri) and parsing (parseUri).
  • Dedicated Handler Logic: A new CustomCollectionHandler class centralizes the logic for processing custom collection requests, including pagination, filtering, and OpenTelemetry tracing.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments or fill out our survey to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions github-actions bot added component/collections Collections related priority/medium Medium priority issues type/feature Requests for new features labels Jul 27, 2025
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces custom collection dispatchers for Fedify, enhancing its extensibility and flexibility. It includes new callback types, methods, and handlers for managing custom collections. I've identified a few critical and medium-severity issues that require attention:

  • Critical Issues:

    • Incorrect function call in fedify/federation/middleware.ts for the collection route handler.
    • Incorrect regular expression for parsing custom collection URIs in fedify/federation/middleware.ts.
  • Medium-Severity Issues:

    • Copy-paste error in an error message in fedify/federation/handler.ts.
    • Code duplication in fedify/federation/handler.ts between _handleCustomCollection and _handleOrderedCollection.
    • Missing function definitions in code examples in docs/manual/collections.md.

@github-actions
Copy link
Contributor

github-actions bot commented Jul 27, 2025

The docs for this pull request have been published:

https://6406bd24.fedify.pages.dev

Copy link
Contributor Author

@2chanhaeng 2chanhaeng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@github-actions
Copy link
Contributor

The latest push to this pull request has been published to JSR and npm as a pre-release:

Package Version JSR npm
@fedify/fedify 1.8.1-pr.332.1207+4291d39b JSR npm
@fedify/cli 1.8.1-pr.332.1207+4291d39b JSR
@fedify/amqp 1.8.1-pr.332.1207+4291d39b JSR npm
@fedify/express 1.8.1-pr.332.1207+4291d39b JSR npm
@fedify/h3 1.8.1-pr.332.1207+4291d39b JSR npm
@fedify/nestjs 1.8.1-pr.332.1207+4291d39b npm
@fedify/postgres 1.8.1-pr.332.1207+4291d39b JSR npm
@fedify/redis 1.8.1-pr.332.1207+4291d39b JSR npm
@fedify/testing 1.8.1-pr.332.1207+4291d39b JSR npm

Copy link
Member

@dahlia dahlia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, I think this is okay to merge, but to be more confident, I think it would be a good idea to create a working example in the examples/ directory. @2chanhaeng Could you please add a sub-issue to issue #310 for creating an example for custom collections?

@dahlia dahlia merged commit c7ac9cc into fedify-dev:main Jul 29, 2025
10 checks passed
@2chanhaeng 2chanhaeng deleted the issue#310 branch August 9, 2025 13:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/collections Collections related priority/medium Medium priority issues type/feature Requests for new features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom collection dispatchers

2 participants