This is something I’ve been thinking about for a while and I’d be interested in hearing thoughts from other AP developers. I run a single user Mastodon instance on a personal domain. I’m not happy with the Mastodon resource usage and I’d like to move to a lighter implementation. My goal is to move my domain with all my content to this new AP server implementation. I want this to be completely transparent to other AP network nodes (requires no changes to their implementations).
Theoretically, this should be as easy as exporting my Mastodon data (maybe directly from the database) and loading it into the new server’s data store. However, the challenge I’ve seen is that AP servers typically hard-code their URI path structures. For example, a note on one server might require a URI structure like
https://server.example/users/steve/statuses/<id>
and on another server, it might require a structure like:
https://server.example/steve/p/<id>
This means I can’t simply import content using the first URI structure into a server requiring a different one.
I typically see server implementations that define route handlers that depend on the URI path structure. Something like…
@app.get("/actors/:id")
def get_actor(request): ...
@app.get("/actors/:id/followers")
def get_followers(request): ...
Based on my experimentation, this seems unnecessarily rigid although I understand it’s the common way of thinking about writing API route handlers.
What if… there were one AP POST route handler and one AP GET route handler? The request URL is the AP URI. This URI can be used to internally dereference the target resource and do routing and validation based on that resource independently of the structure of the HTTPS URI. Something like (pseudocode):
@app.get("/:path")
def get(request): ...
uri = get_uri(request) # adds the scheme://domain prefix
resource = dereference(uri)
return serialize_to_jsonld(resource)
@app.post("/:path")
def post(request): ...
uri = get_uri(request) # adds the scheme://domain prefix
resource = dereference(uri)
# validate target resource
# perform side-effects
For a GET, the server would attempt to dereference the resource based on the URI and serialize it to AP JSON-LD.
For a POST, the target resource is an inbox or outbox. Given the URI, the server can dereference the target resource and verify that it’s a OrderedCollection
. Assuming an attributedTo
property is defined for the box (a good idea in any case, IMO), the actor can be dereferenced and the server can determine if the box is an inbox, outbox or an invalid resource.
At that point the processing can continue without any dependencies on a specific URI structure.
When local resources are created, a server may have a preferred URI structure but that wouldn’t prevent others from being supported in the same implementation. A server could even allow each installation or even each user to select from a set of preferred URIs in a similar way to WordPress supports different permalink structures.
The other potential issue is that some servers implement resource stores that depend on a specific URI structure (like subdirectories or tables that correspond to a URI path structure). To be flexible, the resource store should be able to dereference a resource based on an opaque URI. For example, a server that uses files for storage might hash the URI and use that as the resource file name.
The shift in perspective here is thinking in terms of resource URIs instead of URL endpoint routes.
Thoughts?