Hacker News new | ask | show | jobs
Go-Fed: ActivityPub in Go (go-fed.org)
56 points by lolsoftware 1295 days ago
4 comments

https://github.com/superseriousbusiness/gotosocial is another ActivityPub implementation in Go. It implements a full server and aims to provide Mastodon-compatible client APIs. Lots of cool work going on in this space.
https://github.com/superseriousbusiness/activity [1] is actually forked from go-fed/activity, so they are not really different implementations. I don't know why go-fed is on here honestly, it's just a library, and one that isn't used directly for anything at the moment.

[1]: https://github.com/superseriousbusiness/activity

It’s been an enjoyable experience getting this to run on fly.io . Still working out a few bugs but the team has been very responsive on my bug reports.
I just tried using the app tutorial the other week as a newcomer to ActivityPub. I found it rather difficult to follow because it's so abstracted and it has you dive in head first doing a lot at once. And there are parts left as an exercise to the reader, which leaves gaps that makes it harder. And there are a few bugs in the tutorial code to boot. I feel like the author was very thoughtful about the whole thing, and very thorough, which I appreciate, but was too deep into it to put himself in the headspace of someone who is new to ActivityPub per se. Just my guess, of course.

I'm trying go-ap now and it's better in that I can jump in and use small parts of it, but it still could use more documentation.

Hi, I'm the developer of go-ap, thank you for your interest.

Which parts of it are giving you trouble? I'm always open to answer questions to the project's mailing list: https://lists.sr.ht/~mariusor/activitypub-go

There is a rather hidden wiki that has some more information than strictly the comments in the code: https://man.sr.ht/~mariusor/go-activitypub/

If you are looking for examples, there is a reference server at https://github.com/go-ap/fedbox

Outside of that, any submission for documentation from your part would be greatly appreciated, like you already said, if you work with the specification for a long time it's sometimes difficult to put yourself in the shoes of someone new. I would greatly appreciate such a perspective.

Thanks, I appreciate that you're interested in this feedback. I didn't know how much I should be bombarding the github issues. I posted the github issue in fedbox about making cs2.md easier to find. (to that end - if there's a hidden wiki, make it not hidden!)

Nothing in particular is giving me trouble. It's just that reading through fedbox (which I think is billed as a "simple" example) there's a lot going on and I don't know what exactly I'm looking at or where to start looking (though over time, especially after finding cs2.md, I'm starting to). The first hook for me was the definition of the "Service" actor, and I said "ah hah. so if I do this, but make it a Person, and fill in these attributes, it'll help me generate a json response of a Person actor" Then after spending time looking at errors with json.Marshal I realized that I need to be using jsonld.Marshal instead. That detail was never put in front of me. Then I had to dig through various repos to find how to add the "@context" fields. Right now I'm figuring out what exactly the Inbox and Outbox things do for me (maybe just generate a path?) And so on. I don't imagine this is how you want us to figure out how to use go-ap. Similar to the go-fed developer, it seems like you may not realize how much understanding you're taking for granted.

I think someone like me could benefit from a real stripped down example, no currying (pretty cool, never seen it before in Go, but a bit confusing), no layers of indirection, normal Go http handlers, the simplest database option. Let me do fancy abstractions in my own app once I learn how the libraries work. And/or a README that gives the lay of the land.

Yes, I can understand your frustrations, which stem probably from looking at the subprojects of go-ap as separate entities, when actually they form a whole library that can be used to create an ActivityPub server.

FedBOX was meant to be a "simple" example, but that was some years ago, and as these things go, I piled on work on it and now supports multiple storage backends, has its own oauth2 end points and storage, etc. I'm actively working on extracting from it the pieces that can be independent, to leave just the glue that combines the different parts of the library into a coherent and hopefully "simple" application.

Regarding your feedback, I'll act on making the wiki more visible and maybe make time to add some clarification why we need the separate jsonld package all together (which I thought it's implied because the ActivityPub specification states it in its first paragraphs). I guess I can clarify in the docs who the projects target: a go developer that wants to work in the fediverse space, has read a little from the specification but decided that code would be more understandable - which is I guess the point where I was at when I started them. :D

> sub-projects of go-ap, separate entities

That part made sense once I read that fedbox puts it all together.

> extracting from fedbox to make simpler examples

Great!

> Read the specification

I have, maybe not carefully enough. I knew what jsonld was. I didn't notice at first that the structs in go-ap were annotated with `jsonld:"..."` rather than `json:"..."`. Perhaps jsonld.Marshal handles turning embedded objects into links? Otherwise I'm not sure what in the spec should have indicated to me that json.Marshal wouldn't work, since jsonld is still json.

> since jsonld is still json.

When it comes to the Go the standard library implementation, that's not really the case. Go doesn't deal very well with the dynamic nature of the linked data. A lot of the architecture of go-ap has to deal with the fallout from this one issue. :(

On the wiki I mentioned before I wrote an explanation that goes over the problem a little more in depth: https://man.sr.ht/~mariusor/go-activitypub/go-ap/index.md#de...

So, if it's useful, maybe I could start by adding basic things to the READMEs as I learn them.
That would be useful, but I would prefer you add to the doc/ folder instead of the README.
I’ve heard ActivityPub has mixed reviews. Perhaps someone here with a little more expertise can answer this question.

Does ActivityPub have a batching mechanism?

Imagine you are on server A and you have 3000 followers on server B. If you create a post do 3000 messages get sent to server B? Or just one?

> 7.1.3 Shared Inbox Delivery

> For servers hosting many actors, delivery to all followers can result in an overwhelming number of messages sent. Some servers would also like to display a list of all messages posted publicly to the "known network". Thus ActivityPub provides an optional mechanism for serving these two use cases.

From https://www.w3.org/TR/activitypub/#outbox-delivery

You don't necessarily have a sharedInbox though, I think?
Servers are not required to provide a shared inbox, but if they want to enable batching behavior they can. Not sure if that's what your asking?
AFAIUI yes, you will probably get 3000 messages sent because each follower has their own inbox. There is a potential for batching though - "a server MAY reduce the number of receiving actors delivered to by identifying all followers which share the same sharedInbox who would otherwise be individual recipients and instead deliver objects to said sharedInbox" - if a bunch of the 3000 followers have the same sharedInbox (which presumably the receiving server has somehow magicked up?[1]), then your server can do a bulk delivery to that for those followers.

[1] I guess you might make them for specific celebrities if your server has a high density of followers? grepping the Pleroma source doesn't seem to throw up any obvious "automatically make them" logic.

Generally, all followers on a single server share the same sharedInbox. To a first approximation, that's what "server" means on ActivityPub—sharing a "batch" inbox you can deliver to.
> Generally, all followers on a single server share the same sharedInbox.

You mean that all followers of Celebrity X on instance Y will have a sharedInbox because they're a follower of Celebrity X? Apologies, I've only lightly read the spec and haven't really seen anything like this in there.

No, sorry, what I mean is that all users on mastodon.social have a unique private inbox and then a "sharedInbox" value of "https://mastodon.social/inbox". Almost all deliveries (with appropriate "to" and "cc" targeting values that the receiving server can appropriately deliver to, i.e. individual actors or the special "followers" group for an actors) can be sent to the sharedInbox in bulk, but for private groups and some other special cases you may want to use direct delivery.
Can this run on a mobile device similar to Matrix’s Dendrite server running on mobile?
probably, but the hard bit of doing that is needing the p2p overlay network to provide connectivity - eg Pinecone is what we use for P2P Matrix (see https://arewep2pyet.com)