nodeSolidServer / node-solid-server

Solid server on top of the file-system in NodeJS
https://solidproject.org/for-developers/pod-server
Other
1.78k stars 303 forks source link

Implement ActivityPub #621

Open csarven opened 6 years ago

csarven commented 6 years ago

http://www.w3.org/TR/activitypub

Implement AP where applicable. LDP container representation as AS2 collection of items (semantic overlap), and actor's outbox should be high priority. Response body in compact JSON-LD is required.

Going forward, full fleshed ActivityPub implementation should probably be an extension, if the core node-solid-server is to operate as a server in federation mode..

melvincarvalho commented 6 years ago

@csarven I've added a thumbs up to this.

My position was always to give it a year or so, in order to see what traction it gained.

I think the fediverse has done that now, with over a million users, many of whom share our values

https://en.wikipedia.org/wiki/Fediverse

The issue is that we dont have anyone to work on this. If you'd like to throw some cycles into design, I think that could be helpful.

Possibly a baby step in this is to implement a minimalic webfinger, leading to listing solid on the wiki page.

Another may be to add activity+json to our list of RDF mime types, and send the data to the JSON-LD parser

rhiaro commented 6 years ago

Webfinger is not part of ActivityPub. It uses FYN just like Solid, with some specific predicates from the AS2 vocabulary.

melvincarvalho commented 6 years ago

@rhiaro That's a great point! It should be a separate issue.

I was looking at the comparison matrix here :

https://en.wikipedia.org/wiki/Fediverse#Fediverse_software_platforms

Where most that have implemented activity pub have also implemented webfinger. They seem to kind of go together. So the quick win would be to become part of the fediverse.

I'm looking at what it would take to be a consumer of the activity+json mime type.

It would seem that adding activity+pub here

https://github.com/solid/node-solid-server/blob/d18dd6e9f06f57f7acfca8683f00c027ecb9ab22/lib/ldp.js#L32

and sending it to the JSON-LD parser might be a good start.

But I dont have an insight into whether or not activity+json data in the wild is valid RDF.

melvincarvalho commented 6 years ago

And I think the other part would be to add it to rdflib here :

https://github.com/linkeddata/rdflib.js/blob/c0f921e1cfe3722a86549174828d32e31b5358db/src/parse.js#L41

With the tests at

https://github.com/solid/node-solid-server/blob/6f160a5f3000862c6f55d68dcda1aeaa52e4a5b9/test/integration/formats-test.js#L23

melvincarvalho commented 6 years ago

Note : After some activity pub integration, it may be possible to get listed here

https://github.com/thefederationinfo/the-federation.info#how-to-get-your-platform-listed

How to get your platform listed

Implement NodeInfo, NodeInfo2, Statistics.json or Mastodon stats API endpoint.

sebilasse commented 6 years ago

@melvincarvalho ActivityPub support is awesome. Could you reopen this issue ?

@rhiaro While I agree that webfinger and ActivityPub are two separate specifications it would be nice to read a sentence about why webfinger can help ActivtyPub to satisfy the Fediverse on https://activitypub.rocks.

RubenVerborgh commented 6 years ago

@sebilasse Note that it is not "closed closed" as in the sense that we wouldn't want to tackle this. Rather, it is tagged "revisit", which means that it is something we want to do at some point in the future.

We've made this change such that open issues reflect current bugs and priorities. So let's not reopen, unless someone wants to be assigned (in which case, be my guest).

melvincarvalho commented 6 years ago

What @RubenVerborgh said. We are still at design phase, we need concrete steps of how to implement this, and we also dont have anyone to assign it to.

I propose to break down the task into smaller chunks, review pieces, and create a plan for implementation. Also needed would be some resources that will commit to testing the maintenance.

IMHO the low hanging fruit right now would be to allow node solid server to become a consumer of activity+json type data. We have recently run it through the JSON-LD playground and there were no alarm bells. One open question I have, is what the activity+json file type is. For example turtle is .ttl, and json-ld is .jsonld, activity+json seems relatively under specified in this regard.

Would like to see this move forward, and given the increased traction of both mastodon and solid, it's possible someone will step up.

sebilasse commented 6 years ago

@melvincarvalho The spec. says

MUST present the ActivityStreams object representation in response to application/ld+json; profile="https://www.w3.org/ns/activitystreams", and SHOULD also present the ActivityStreams representation in response to application/activity+json as well

So isn't the filetype .jsonld ? @rhiaro

@RubenVerborgh In general I'd be happy to help with this. Also pinging @cwebber [-> ActivityPub for SOLID]

RubenVerborgh commented 6 years ago

I think we will not be able to implement that until #661 and #662 are incorporated (which we need for proper conneg) and they are unfortunately a lot of work.

elf-pavlik commented 6 years ago

So isn't the filetype .jsonld

From what I recall application/activity+json has implicit JSON-LD context mandated by the spec. Because of that generic JSON-LD tooling can not handle it and it requires adding custom support for application/activity+json It might make more sense to have solid server extensible so that someone could implement ActivityPub as an extension. The ActivityPub RPC orientation with various side effects does seem a little bit different from Solide REST orientation and more generic purpose approach.

cwebber commented 6 years ago

Yes, @elf-pavlik has it right. (This comes from ActivityStreams rather than ActivityPub itself.)

BTW, very happy to hear about this! Getting the REST'y people and the Linked Data people to get along in the Social Working Group was a big win. Convergence! :)

melvincarvalho commented 6 years ago

How about a shared etherpad, where we can discuss a path to convergence?

gobengo commented 6 years ago

I have a bunch of TypeScript (any node.js can link to it as JS) code for various parts of an ActivityPub implementation in https://github.com/gobengo/distbin/blob/master/src/activitypub.ts

I'm down to extract a lot of it into a more generic library if anyone has thoughts on what sort of API might make sense.

boulderwebdev commented 5 years ago

@elf-pavlik, @melvincarvalho I agree with having an implementation of ActivityPub abstracted away from the node-server, but I think it's better to build this is as a separate server and have the two communicate with each other over some REST API. This has the benefit of allowing for different implementations which are optimized for specific application behaviors.

melvincarvalho commented 5 years ago

@boulderwebdev that could work really well! Would love to see a sketch high level design of that.

melvincarvalho commented 5 years ago

Will close this for now, as we dont have anyone working on it, and it's typical to close threads marked with 'revisit'. I've identified a couple of places I think we can move forward, tho.

If someone wants to help with take this forward or design, that would be great.

boulderwebdev commented 5 years ago

@melvincarvalho The most naive approach would be to forward messages from the node-server to the ActivityPub server. So my GET and POST requests with an application/activity+json Accept/Content-Type header could be forwarded over to the activitypub server and the response could be routed back through the node server. One problem with this is that it forces the developers of an app to use only one activity pub server which is dependent upon the node-server. While it's not necessarily bad (and probably a useful default) that the node server has a default ActivityPub server attached, it's definitely not desirable in an environment with multiple use cases.

One example situation which would cause the server to either lock up or crash for a non-trivial amount of time is if you have a social networking app where the friending model is a directed graph e.g. Twitter's following/follower model for managing user interactions. In this case you could have a user with a large following, and any time they create a new piece of content that needs to be sent out to their tens of millions of followers, then the server sending these messages may have a difficult time finishing.

So in this case it may be better to allow the user to configure ActivityPub servers to manage their requests for different resources. This could be done by creating a configuration file in the directory you wish to use as a resource, let the solid server read the configuration file, and have this message forwarded to the corresponding ActivityPub server.


Also, I could go through the entire ActivityPub and sketch what an implementation could look like, if the community likes this idea.

kjetilk commented 5 years ago

I need to read the ActivityPub spec properly (only skimmed it thus far), but my feeling has been that "an inbox is a resource that has an event handler bound to it", and so, it seems to me that handling the ActivityStream on an RDF level in such an event handler would be an interesting way to go.

Now, the focus is on 5.0.0, but we will soon emerge from under that and start looking forward, and I have put ActivityPub on my list of things to keep in mind going forward. So, you may want to defer a little bit until we have gotten our heads above water. :-)

melvincarvalho commented 5 years ago

Great stuff. Main question I think is should it be part of NSS, an extension, or run as another server on the same box. Or some combination of all three. I think at this point a clean modular design would seem beneficial so that the core server can be marked as a stable reference implementation without other languages having too much too copy. But as usual, it will probably come down to who is prepared to work on it.

RubenVerborgh commented 5 years ago

Caveat here is that the current server does not support such a modular design. So without significant work on the server, building this as part of NSS or as an extension is not realistic, so another process is currently the most viable way.

gobengo commented 5 years ago

@boulderwebdev

The most naive approach would be to forward messages from the node-server to the ActivityPub server.

Ha, and I think we can think about it the other way too. There is a server that speaks ActivityPub, and it persists all incoming inbox items to a Solid store (instead of a filesystem or networked database). This ActivityPub-speaking server could ideally run statelessly and headlessly. You'd browse your inbox using a Solid UI.

I think it's better to build this is as a separate server and have the two communicate with each other over some REST API.

Me too. The REST API can just be Solid.


The main logic of distbin just depends on activities and inbox objects that implement the key-value [Map]() interface. Well actually it's AsyncMap, with the same API but any of the things can return promises. By default I use an implementation that saves things to JSON files on the filesystem, JSONFileMapAsync. But a SolidAsyncMap(baseUrl) whose implementation of .set(key, val) makes HTTP calls to a remote server, could totally be done and used instead.

Then filling out the form at the distbin instance using SolidAsyncMaps would result in new entries in your node-solid-server storage and any solid-compatibel app you use to browse it.

boulderwebdev commented 5 years ago

@gobengo

Ha, and I think we can think about it the other way too. There is a server that speaks ActivityPub, and it persists all incoming inbox items to a Solid store (instead of a filesystem or networked database). This ActivityPub-speaking server could ideally run statelessly and headlessly. You'd browse your inbox using a Solid UI.

The problem with this is that it is not very scalable. For example, I ran a test to send 1000 notifications using this strategy and it took ~13 seconds on my i5-5300u laptop with 16gb of RAM. If you even had a medium size of friends, say a million, this would take around 3.6 hours to accomplish, assuming the browser doesn't blow up or complain. This kind of UX is completely unreasonable

timbl commented 1 year ago

A million is a "medium" number of friends? Suppose I stream we build systems which work for thousands of groups of thousands not millions of people. If 13 secs in the background gets you the interop and functionality you want, that would be use to look at .. move it to a separate box after testing on laptop. Yes running an AP sever with all the state in Solid could be useful.

melvincarvalho commented 1 year ago

There is quite a bit of new activity in the SWICG and it's also in the "someday" pile in the SolidOS Task Manager

There is talk about an ActivityPub primer as a W3C Note. Perhaps one idea would be to use a standards based approach, such that fediverse users are able to benefit from personal storage, and Solid users benefit from Microblogging, and other apps.