Webfinger for non-actor objects and storing foreign objects

Hello! This is my first post here, I hope I’m not breaking any rules. :slight_smile:

I am writing a simple wiki in Go, which is my first project using ActivityPub. Each wiki has articles, and the user can create and edit articles on their home instance and on remote wikis, and each article is identified by its title. I was wondering if it is possible to use webfinger to resolve the title of an article to its URI, so that an editor of a wiki can, for instance, link to a foreign article that has not been previously fetched by typing [[Lambda calculus@comp.wiki]] instead of copying the article’s uri. I’m not sure how to implement this, what URI scheme to use and whether there are better ways of solving this problem. I’ve searched the forum and looked at similar software such as WriteFreely, but could not find a similar usage of webfinger.

I am also unsure on whether I should store all articles from other instances. Ibis seems to fetch and store not only the articles, but also all of their edits from other instances. Without this, however, the user would have to use the URIs of these edits to identify them, right? and this would result in very long, inelegant URLs. What approach would you recommend for a project that aims to be small and simple?

2 Likes

While you could theoretically use WebFinger to look up anything you want, it’s not a standard use of the protocol, so you shouldn’t expect other servers to know how to use it this way. I’d review the specs from webfinger.net – you can either send a URL or an acct: URI.

I’m not sure how Ibis is doing it (it looks like a phenomenal project, btw) but I’d think you’d want to store copies (even just summaries) of every article you want to appear on your server. When you receive an Update message, then you could apply those updates to your local copy – or even better, just download the whole new version of the article from the original source.

On a separate note, it’s great to see other Gophers building on the Fediverse. I’ve built a whole stack of libraries to make this easier. I’d love to know if any of these could help you build your Wiki.

2 Likes

@SidereusNuntius

In Fediverse, ‘acct’ URIs are expected to resolve to actors, but webfinger can be used with any kind of URI. You can even invent your own, e.g. wiki:Lambda_calculus@comp.wiki

1 Like

i suppose it is possible to do this with webfinger, and in theory, webfinger does something very similar to this – it resolves a resource name to a resource descriptor, and that descriptor might have links or aliases. but the main question i’d have is if it’s necessary to do this.

it seems like you envision links to remote articles in the form [[$NAME@$ORIGIN]], so some considerations for this:

  • do you not allow @ to appear in article names? consider that @ might appear in wiki article names already, such as https://en.wikipedia.org/wiki/@_Meh or https://en.wikipedia.org/wiki/M@PS (and this could make your parsing more complicated). taking inspiration from Wikipedia:Naming conventions (technical restrictions) - Wikipedia might be a good idea.
  • i’m guessing you want spaces to be allowed, so you probably need to figure out if they should be encoded as _ or - or + or %20 or something else in your nameserver/resolver queries.
  • how do you imagine the federation to work? it is possible to use local redirects and namespace your references instead like [[comp.wiki:Lambda calculus]] or [[comp.wiki/Lambda calculus]] if you know ahead-of-time which namespaces map to remote wikis. but this is already very similar to just using URIs, just with some slight translation. what’s the difference between [[comp.wiki/Lambda calculus]] and [[https://comp.wiki/Lambda_calculus]], really? internally, you would have your wiki namespace redirect to whatever you configure it to redirect to. you can already do this with a web server like nginx:
location ~ /comp.wiki/(?<name>.*) {
  return 307 https://comp.wiki/$name;
}

if you’re set on requiring each host to run their own resolver for some reason, you would need to agree on a base resource and a link relation. if you expected the base to always be a domain/host, then you could use host-meta, which is like webfinger but served at /.well-known/host-meta and /.well-known/host-meta.json and not taking a resource= parameter. if you wanted to allow for base resources, then you would use webfinger with the resource= parameter. either way, say you define a link relation https://rel.example/:

<https://rel.example/>
  rdfs:label "has wiki articles following a template"@en;
  rdfs:comment "This link relation defines a link template with the variable {name}, which denotes the name of the wiki article."@en.

you then have one of your links use this rel, with a template. take your pick:

GET /.well-known/host-meta HTTP/1.1
Host: domain.example
Accept: application/jrd+json

{
  "links": [
    {
      "rel": "https://rel.example/",
      "template": "https://domain.example/wiki/{name}"
    }
  ]
}
GET /.well-known/host-meta.json HTTP/1.1
Host: domain.example

{
  "links": [
    {
      "rel": "https://rel.example/",
      "template": "https://domain.example/wiki/{name}"
    }
  ]
}
GET /.well-known/webfinger?resource=https://domain.example/ HTTP/1.1
Host: domain.example

{
  "subject": "https://domain.example/",
  "links": [
    {
      "rel": "https://rel.example/",
      "template": "https://domain.example/wiki/{name}"
    }
  ]
}

in that last example, we assume a convention where the https uri of the domain root is equivalent to the host service itself. that is to say, https://domain.example/ represents the host and not some other resource (a page, a person, etc). this is not universally agreed upon, but it could make sense to assume/require.

once you have the link template, you plug in the variable, which according to RFC 6415 3.1.1.1 must percent-encode any character that is not unreserved. so Lambda calculus would become Lambda%20calculus and get plugged in to yield https://domain.example/wiki/Lambda%20calculus. if this is a problem and you want underscores instead (or some other encoding rules), then this would need to be defined as part of the link relation using different variable names, or otherwise you expect/require all remote wikis to set up their own redirects that convert the %20 back to _.

personally, i would be inclined to keep it simple and just use wiki links with namespaces and local redirects, if i didn’t want to use URIs for some reason. it depends on how you want to parse wiki links, i suppose? as in, how you want to handle certain potentially problematic characters, as per Wikipedia:Naming conventions (technical restrictions) - Wikipedia or whichever technical restrictions you end up with due to your wikilink parsing format.

another possibly related interesting thing you could look at is N2T Home for how to resolve arbitrary namespaces using templates. for example, https://n2t.net/.info/wikipedia