Documentation Wiki

This document is a work in progress and will evolve as we clean up the API.

The main purpose of this document is to establish the API for version 1.0 of the library.

The structure of the models will be different than what it is today.

The vocabulary

Generating code should start from a Go struct with annotations.

The steps should be something like this:

Structure

We need to validate the struct’s compatibility with the Vanilla AP objects:

Helper functions

Generate helper functions:

Types

Accumulate types for generated objects and add their types to the slices for:

Accumulate types into the interfaces that can be used by generic code (Actors, Objects, etc).

The state machine

The ActivityPub state machine needs to operate the following:

  1. Validate received Activity.
    1. Determine which properties need to be dereferenced.
    2. Dereference properties and save them in local storage.
    3. Validate dereferenced objects.
  2. Persist flattened activity to storage.
  3. Operate Activity side-effects.
  4. Aggregate recipients.
  5. Dereference recipients.(?)
  6. Disseminate to local recipients.
  7. Disseminate to remote recipients.

Data types

We need some interfaces that unifies behaviour between client to server and server to server logic.

We should establish if the current authorized actor needs to be part of the API, or we can leave it as an implementation detail.

The implementations for the Processor and Validator would be scoped per each section of the specification:

// dereferencer is a helper interface that gets used 
// by the [Validator] to enrich an activity with additional information.
type dereferencer interface {
	// Maybe Load instead to keep it similar to readStore? 
	// (but without the filters?)
	Fetch(iri vocab.IRI) (vocab.Item, error)
}

// disseminator is a helper interface that gets used
// by the [Processor] to submit activities to recipients.
type disseminator interface {
	ToCollection(colIRI vocab.IRI, it vocab.Item) error
}

// readStore is a helper interface that gets used
// by the [Processor] or [Validator] to retrieve 
// objects and activities from *local* storage.
type readStore interface {
	Load(iri vocab.IRI, ff ...filters.Check) (vocab.Item, error)
}

// readStore is a helper interface that gets used
// by the [Processor] to save objects and collections to *local* storage.
type writeStore interface {
	// Save saves the incoming ActivityStreams Object, and returns it together with any properties
	// populated by the method's side effects. (eg, Published property can point to the current time, etc.).
	Save(vocab.Item) (vocab.Item, error)
	// Delete deletes completely from storage the ActivityStreams Object, this is usually
	// a side effect of an Undo activity.
	Delete(vocab.Item) error

	// AddTo adds "it" element to the "col" collection.
	AddTo(vocab.IRI, ...vocab.Item) error
	// RemoveFrom removes "it" item from "col" collection
	RemoveFrom(vocab.IRI, ...vocab.Item) error
}

// store is a helper interface that gets used
// by the [Processor] or [Validator] to retrieve and/or store 
// objects and activities from *local* storage.
type store interface {
	readStore
	writeStore
}

type Validator interface {
	// ValidateActivity validates an activity.
	// It dereferences all properties that need to be dereferenced and validates it.
	// The "it" parameter gets enriched with the dereferenced properties. 
	Validate(ctx context.Context, it vocab.Item) error
}

type Processor interface {
	// Process processes the incoming activity
	// The "it" parameter gets enriched with whichever additional information operating 
	// the activity adds.
	// Eg. In the case of a Create activity operated in an outbox collection, its Object 
	// would receive an ID, or the Published property gets added if they're missing.
	Process(ctx context.Context, it vocab.Item) error
}