Problem/Motivation
I am practicing some dark arts involving setting default query parameters for json:api resource endpoints if they are not set in the client request. I want to back these defaults out of the pagination URLs sent back to the client because 1) they're defaults, and don't need to get sent back to the server and 2) reveal some of our back-end logic (that is, I don't want the client to know some of the defaults.)
I initially thought I could do this with an outbound path processor, but it turns out that json:api in core does not give the path processors any opportunity to act on the generated URL, by virtue of the fact it simply reflects the request URL.
See https://git.drupalcode.org/project/jsonapi/-/blob/a6f230f3641214be7a2b5e...
I did some archaeology and found where this was implemented...looks like @wimleers changed this at #2937797-35: Entity UUID Converter performance. The surrounding discussion was about avoiding calls to the param converter?
https://git.drupalcode.org/project/jsonapi/-/commit/fd0c2e7#ca9c156ebc07...
The outbound path processor does not get called because the Url::fromUri() sets the URL object's unrouted flag, and Url::toString() uses that flag to send the processing down a path which does not do outbound processing, because it considers the URL to be "external."
Steps to reproduce
Try to apply an outbound path processor to pagination URLs.
Proposed resolution
I think the solution here is either to:
- Strip the site's base path from the request URL, essentially turning it into a relative URL when it gets processed in the
Linkconstructor. There are some examples of this (or the inverse) being done in core and contrib but it feels a little rough. - Change
UnroutedUrlAssembler::buildExternalUrl(), which is what gets used now, to consultUrlHelper::externalIsLocal(), and conditionally do outbound path processing akin to what is done in UnroutedUrlAssembler::buildLocalUrl(). I like this best, and it improves the DX of URL generation even more broadly.
Comments
Comment #2
bradjones1See related for proposed approach #2.
Shower thoughts on this: It would appear to me that re-using the URI from the request object is the easiest/least computational/path of least resistance in reflecting the URL back to the user. It's not 100% ideal, but the whole ideal of canonical routing in json:api is a bit different than Drupal's traditional approach.
I'm not going to mark this postponed/duplicate in case someone else has some better ideas on handling this simply within json:api.
Comment #6
arun.k commented@bradjones1 we need more information and steps, how to check it.