The GoActivityPub library contains the building blocks for adding ActivityPub functionality to both client and server applications for the Go programming language. It is a robust, “batteries included” product with a high level of interoperability with the rest of the Go ecosystem.
The focus is on high spec compliance, minimal external dependencies, and minimal computing requirements.
Another tenent of the way the library is designed is to ensure the ActivityPub functionality does not try to go around other existing specifications related to content on the world wide web, and tries to ensure there’s a high degree of coherence with them. ActivityPub builds on multiple HTTP related specifications and we want to honour that legacy, from content negotiation to caching and to resource authorization.
The library is divided into functionally independent modules connected through interfaces.
The official repositories for the project are hosted under the go-ap GitHub organization.
The high level overview on the project offers the following distinct pieces:
- The Activity Vocabulary data types for Go.
- The ActivityPub state machine which deals with processing different activities, handling their side effects and disseminating them and their objects to recipients and collections.
- Multiple custom storage backends specifically created for ActivityPub objects and supporting a standardised API.
- An ActivityPub HTTP client with an extended API for both fetching data and submitting activities.
- Authorization mechanisms for this client that support both server to server and client to server algorithms.
For more information about each of them see the module details page.
Design decisions
The main problem of implementing the ActivityPub specification in the Go programming language stems from the very dynamic nature of JSON-LD, which is used as its data format, and the limited (in this respect) features of the Go type system.
This apparent incompatibility stems from the fact that an object property in the ActivityPub specification can have any of the following values:
- an IRI which can be dereferenced to an ActivityPub object
- a full ActivityPub object
- an array of ActivityPub objects
- an array of IRIs to ActivityPub objects.
Because the Go type system can’t express this type union explicitly, we rely on
implementing these four meta-types independently and giving them unifying
behaviour through the Item
interface. Basically if any type implements this interface, it can be used with the
GoActivityPub modules.
To keep in line with Go’s interface guidelines, we have tried to keep the
methods this interface exposed to a minimum, and this led to a very limited
guaranteed API for the main vocabulary type the, vocab.Item interface.
Pitfalls
Stemming from the decisions outlined above the correct use of the library’s modules can have some rough edges in certain respects.
I compiled a list of pitfalls when using them in your own code.
If you find any other issues, please get in touch on the discussion mailing list or on GitHub for the module you’re having troubles with. (The later might be slower to get a response though.)