1
Wiring Up
Gabriel Kaszewski edited this page 2026-05-29 02:09:46 +00:00

Wiring Up

ActivityPubService is the central struct. Build it once at startup, share it via Arc.


Build the service

use std::sync::Arc;
use k_ap::ActivityPubService;

let db = Arc::new(MyDb::new(pool));

let service = ActivityPubService::builder("https://example.com")
    .activity_repo(db.clone())
    .follow_repo(db.clone())
    .actor_repo(db.clone())
    .blocklist_repo(db.clone())
    .user_repo(db.clone())
    .content_reader(db.clone())
    .object_handler(db.clone())
    .allow_registration(false)
    .software_name("my-app")
    .build()
    .await?;

The base URL ("https://example.com") is used for all AP URLs the library generates — actor IDs, inbox URLs, collections. It must match the public URL of your service.

All seven setters are required. Calling .build() before any of them panics with a descriptive message.


Mount on axum

use axum::Router;

let router = Router::new()
    .merge(service.router())               // AP routes owned by k-ap
    .route("/users/:id", get(actor_handler)) // your routes
    // ... rest of your routes
    .with_state(app_state);

service.router() registers 7 routes. See Routes Reference for the full list and the content negotiation pattern for actor/followers/following.


Optional builder settings

Method Default Description
.allow_registration(bool) false Reported in NodeInfo openRegistrations
.software_name(&str) "" Reported in NodeInfo software.name
.delivery_max_attempts(u32) 3 Max retry attempts per delivery
.delivery_initial_delay_secs(u64) 1 Initial backoff before first retry (doubles each attempt)
.event_publisher(Arc<dyn EventPublisher>) in-process spawn Route delivery/backfill through a job queue
.debug(bool) false Enable debug mode in activitypub_federation

Real-world examples

Both implement all seven traits on a single Arc<Db> struct:

  • thoughts — microblogging; one of the sources k-ap was extracted from
  • movies-diary — movie logging; the other source