Page MenuHomePhabricator

Provide a way to obtain the URL of a REST endpoint on another wiki
Open, LowPublic

Description

Currently it is not possible, from within a REST endpoint, to obtain the URL of another endpoint on another wiki (on the same wiki farm). Some related functionality already exists:

  • You can obtain the URL of another route on the same wiki via $this->getRouter()->getRouteUrl()
  • You can obtain URLs (mostly of pages) for another wiki via methods in WikiReference

However, neither option will give you a foreign route URL. This could be useful e.g. for cross-wiki redirects, for which we have a use case in the CampaignEvents extension.

Event Timeline

It's a bit hard to find the right tags for this task. I'm working on at least making it possible to get the base URL of a foreign rest.php endpoint via WikiMap / WikiReference. I don't know what the REST Router part might look like though.

Change #1013109 had a related patch set uploaded (by Daimona Eaytoy; author: Daimona Eaytoy):

[mediawiki/core@master] Add ScriptPath to WikiReference

https://gerrit.wikimedia.org/r/1013109

Change #1013110 had a related patch set uploaded (by Daimona Eaytoy; author: Daimona Eaytoy):

[mediawiki/core@master] Add WikiReference::getEntryPointUrl and WikiMap::getEntryPointURL()

https://gerrit.wikimedia.org/r/1013110

MSantos subscribed.

@Daimona I see that the patch is targeting things to MW-1.42-release so I tagged it as such because the release is upcoming and this also means you should decide wether this is a blocker to release or not.

Change #1013110 had a related patch set uploaded (by Daimona Eaytoy; author: Daimona Eaytoy):

[mediawiki/core@master] Add WikiReference::getEntryPointUrl and WikiMap::getEntryPointURL()

https://gerrit.wikimedia.org/r/1013110

That looks like a good thing to have in general, but it does not take into account RestPath. That will become problematic when we want to put the endpoints behind a gateway use a "nice" path for easier handling in the cache layer.

If we can assume that RestPath will always be the same across all our wikis, we can make this work without too much trouble. If we don't want to assume that (or allow building API URLs for wikis outside our cluser, e.g. translatewiki.org), this gets quite tricky. That'S also why this feature doesn't exist yet - we didn't want to get into this complexity without a clear use case.

@Daimona I see that the patch is targeting things to MW-1.42-release so I tagged it as such because the release is upcoming and this also means you should decide wether this is a blocker to release or not.

Thanks! I think this isn't urgent, especially considering that it doesn't seem easy to do, hence removing the 1.42 tag (and status of release blocker).

That looks like a good thing to have in general, but it does not take into account RestPath. That will become problematic when we want to put the endpoints behind a gateway use a "nice" path for easier handling in the cache layer. If we can assume that RestPath will always be the same across all our wikis, we can make this work without too much trouble. If we don't want to assume that (or allow building API URLs for wikis outside our cluser, e.g. translatewiki.org), this gets quite tricky.

Ooooooof, I didn't even realize we had a separate config variable for the REST entry point. Indeed, it would make things more complex. Even if we marked RestPath as a required setting for $wgConf, it still means we wouldn't have a uniform way of locating MW entry points, which my approach above relies on.

That'S also why this feature doesn't exist yet - we didn't want to get into this complexity without a clear use case.

I think cross-wiki redirects and API calls would be the main reason. For redirects (which is the use case my team has today), I don't think we have a precedent, given that support for global-ish things in MW core is iffy at best. Still, I would see some potential use cases for it, such as global user pages (for instance, https://en.wikipedia.org/w/rest.php/v1/page/User:Daimona_Eaytoy is currently a 404 because I don't have a local userpage on enwiki).

For cross-wiki API calls, I actually find it surprising that there's no way to programmatically obtain the entry point URL given a wiki ID. MW core already provides the mw.ForeignApi and mw.ForeignRest classes. I don't get how one is supposed to use them if not by 1) hardcoding the URL in the code, which is clearly problematic, or 2) storing the full path of the entry point somewhere, which is also problematic. I guess this goes beyond the scope of this task, but it's still related, and IMHO blocked on the same technical reasons.

Quick summary of my thoughts after talking to @Daimona just now:

  • It would be nice to have a narrow interface for getting endpoint URLs for other wikis. There are several use cases for this, e.g. redirecting to file pages on commons or listing interwiki links.
  • A basic (wmf centric) implementation of such a mechanism would not be very hard, perhaps a week of work between the two of us.
  • Making this work "right" gets us back to T113034: RFC: Overhaul Interwiki map, unify with Sites and WikiMap, wich we have been procrastinating on since 2015.

Given that nothing is currently blocked on this capability, I propose MW-Interfaces-Team takes this on with low priority, to revisit when then need arises.

Discussed this with @daniel today. Here are the relevant points from that conversation (from memory, hopefully I didn't miss anything):

  • This whole mess eventually brings us to the existing confusion between WikiMap/WikiReference vs Site/MediaWikiSite vs interwiki (vs SiteMatrix). This really is an old beast, see T113034 (8.5 years old).
  • WikiMap on its own has a few issues: it sort of behaves like a factory for WikiReference with some utility methods, except it isn't just that; for instance, getCurrentWikiId and friends wouldn't belong in a factory. It does not cache WikiReference objects. And some parts of it are either Wikimedia-specific or badly named, such as WikiMap::getWikiName() / WikiReference::getDisplayName().
  • $wgConf is also a mess in its own. There aren't clear instructions on how to use it; one doesn't even have to use it if they want a wiki farm. Certain settings might not exist in $wgConf (e.g., because they should be the same for all wikis, or maybe they are set through other means). I didn't check, but I think $wgConf also does not account for dynamic defaults. In general, it would be nice to have a proper multi-wiki config system in place that is not wgConf. We wonder whether the following statement can be assumed to be true: "if a setting is not specified in $wgConf, then it means it must be the same for all wikis, and therefore we can use the locally-configured value". Hard to say if this is the case, and it sounds so simple that there's probably something somewhere that breaks this assumption.
  • RestPath makes it so that we can't uniformly access all entry points. There was even a proposal to have separate entry points for each action (such as "view" and "edit"; replacing the &action= query parameter). For the time being, we can mitigate this by not introducing a general method that works for all entry points. However, there's still the problem of getting RestPath inside WikiReference. For $wgConf it might be doable, but the same would have to be done for MediaWikiSite (getWikiWikiReferenceFromSites).
  • A good approach would be to introduce a new interface (a very narrow one) that can be used to get route URLs for other wikis. This would likely be implemented by a new service. REST handlers would then have access to that service (unsure if it would be an instance property in the base Handler class or not). Internally, this new service could rely on fragile mechanisms such as $wgConf; as long as this is only done in a single place in core, it shouldn't be too hard to improve it someday.
  • There's also the question of whether a given endpoint is guaranteed to have the same path for all wikis in the farm. This can probably assumed to be the case for the time being, but it's not guaranteed: there might be differences due to pretty paths, or potentially even just versioning. But again, we can probably ignore this for now, and assume that the path of a given endpoint is the same for all wikis.
  • Also a question of what should the new service take as input: wiki ID or interwiki prefix[ or URL]? Different use cases might benefit more from one of these options. Sometimes we may want to redirect to, or call directly, an endpoint that lives in an entirely different world; for example, in production this might mean translatewiki.net or api.wikimedia.org (just to be clear: there are no current plans of doing so, it's just an example).
  • We agree that there are existing use cases for this work, such as global user pages and file description pages. Also a potential use case with language variant redirects. For all of these, the current approach is to either silently follow the redirect, or to return a 404. It's not always obvious whether something should redirect or 404 (e.g., getting the metadata of a global user page may 404, but getting its content may redirect), but these problems can be addressed later when we actually have a way of implementing the redirect.
  • No good way to use mw.ForeignApi / mw.ForeignRest programmatically. Those would also be affected by RestPath and pretty paths.

We don't have clear next steps on this as far as I can tell. The Campaigns team is not blocked on this work, and therefore it can probably be considered low priority until a new need arises.

Removing myself as assignee because I'm not currently working on this. However, I'd still like to pick this up at some point together with @daniel, if possible.

I am removing this from the global implementation epic, as the MVP work is now done, but this can be tracked separately in our backlog.