General AP clients and servers


Good blogpost: mastodon is not just a server (and why that’s not necessarily a good thing)

We talked about this on the ActivityPub panel at FOSDEM. The reason AP ships with both Client-to-Server and Server-to-Server specs that are very similar to each other is to support this dream of being able to use any AP client with any AP server.

This hasn’t happened, though in ActivityPub’s predecessor the Pump API, we did pull that off with and MediaGoblin being able to use each others’ clients. I think it’s worth discussing, so I figured I’d raise it here!


@cwebber, thanks for bringing this up! I’m wondering why C2S isn’t very common. I’m implementing AP and I wish to implement both S2S and C2S :slight_smile:


I already had a discussion about that topic. I see a problem with C2S: When a C2S will “simply” forward all incoming content (that came through S2S) unchanged to the client, then the client needs to implement the whole interpretation of different AP implementations. One can implement AP/AS2 compatible content in many ways. And server coders have experienced this while coding their implementations. Additionally an app coder possibly should implement a JSON-LD parser as well - and the question is, if such a library is available for all systems.

Additionally there is much stuff missing that is normally part of a regular API like searching for content or users, subscribing to users, fetching all posts of a thread in a single call (including the children and parents of that post), fetching actor data, …


To some extent, this is how email works. The email client builds out features, the server just delivers the messages over SMTP. The client downloads messages from the server via POP or it can simply fetch them via IMAP. That’s a valid approach to ActivityPub, but not one that most implementers are interested in when they can instead build an app-server that is essentially a monolithic ActivityPub implementation, where the client is the server, and a frontend simply manipulates data via some REST API.

The problem is when only one of those paradigms is allowed to effectively exist. I think the critique of all-in-one AP S2S-only implementations is really a critique of the app-centric model, where the application layer subsumes all other layers. Centralized services do this because it makes sense for their business needs; the early ActivityPub implementations are largely clones of those centralized services and thus carried over the app-centric model. This monolithic design is in stark contrast to the Unix philosophy of modular and extensible code that works together.


Note that the “S” side of C2S is not limited to simply forwarding incoming content, depending on the exact type that is being posted to the outbox. Side effects still happen, so extensions can still have the Server do meaningful work.

Two side effects that require nontrivial logic in the server side of c2s in the current spec are:

  • the auto-Create-wrapping side effect the server will do if the client sends a non-Activity type.
  • arbitrary collection management via Add and Remove

So while it is true the client part of c2s will need to interpret the ActivityStreams object (much like a mime type in the HTML world) in order to provide a properly UX, I don’t think the extensions of the future will need to limit all meaningful logic to be in the client part of c2s too.


@cwebber, would you suggest that we, as a community, gather the various ActivityPub extensions together, and every ActivityPub server implements the whole AP spec and tries to support extensions, and every AP client implement the spec and tries to support extensions?

For example, I’m working on a federated project hosting platform (a forge). And one of the decisions I face is: Do I want it to implement the whole AP feature set, including the social stuff, or focus only on project hosting things? For example, one of these social features is authoring messages in which the recipient actor is a person, i.e. sending messages (public or private) to other people. This sounds like a basic feature, but it seems forges tend not to have it! I couldn’t find it in GitLab, and in Gogs, and it seems githu8 once had it but removed it years ago.

So, do I leave that feature to other servers to handle (i.e. ask people to use email / IRC / Matrix / Mastodon / Pleroma / etc. to exchange messages), or do I still implement this feature (and all the other social features) so that my software, in addition to handling projects and repositories and so on, also implements a full social server just like Mastodon?


This seems like it would be up to the project to decide. You can certainly combine whichever social elements you desire with other core functionality. In a federated code-forging environment, you would expect essentially multiple different modules or subenvironments are necessary: one for revision management (e.g. based on git), one for project management (e.g. issues, wikis, and PRs based on ActivityPub/ActivityStreams), maybe one for user-user communications (e.g. based on whatever, could be XMPP or ActivityPub or anything else).

Anyway, there’s certainly nothing requiring re-implementing social messaging into every single application, as seems to be the trend lately. It’s fine for users to communicate out-of-band.


But can I drop all these social features, while still being by-the-spec? I guess in c2s I can decide what my users are allowed to post, but in s2s, if a project or a user gets a Create Note addressed to it, what do I do with it? Return an error on the HTTP request? Or return Accepted and do nothing? Or store and display the note to the user, despite my app otherwise not supporting messages?


I think you could respond with an error, yeah. Or you could silently drop the non-understood Activity, but it makes more sense to return an error.


The activity is understood, it would be a most standard Create Note. I wonder what happens when an error is returned. Say, what Mastodon does about it. And what the spec says. I’ll check.


Is there a running instance of a server somewhere that can be used to play with a possible client?
And are there some java guys out there ?