View API Output links point to frontend

Created on 1 March 2024, 4 months ago
Updated 22 March 2024, 3 months ago

After upgrading to 1.0.0-beta5 all View API Output links are pointing to the nuxt api instead of Drupal.

Referencing issue:
https://www.drupal.org/project/lupus_decoupled/issues/3414438#comment-15... πŸ› 'breadcrumb' metatags do not point the frontend Fixed

Analysis done while testing a fix

First:

An underlying issue: BaseUrlProvider::getAdminBaseUrl() (and therefore BaseUrlProvider::getApiBaseUrl()) gets rewritten to a frontend url now! (I missed that and none of our existing tests failed.)

We need to introduce some check to prevent this. I added a new URL option 'lupus_decoupled_skip_rewrite', which seems the cleanest fix to me, even though I don't really like introducing a special option. (There is an alternative fix to this issue: see comment #6 for all details.)

Then:

Based on that change, we need to fix the "View API output" links. We could do that

  • by setting $options['lupus_decoupled_skip_rewrite'] when generating those links,
  • or by never rewriting base URLs when $options['base_url'] is set already.

To me, it feels clearer to do the second thing. it would be good to try to contain usage of $options['lupus_decoupled_skip_rewrite'] to just BaseUrlProvider::getAdminBaseUrl(), and the general $options['base_url'] check feels potentially useful for other future code that sets it.

I don't have proof for that feeling. But... now that we've broken things already anyway in 1.0.0-beta5, and now that we have tests for all situations we know to be significant... I feel comfortable introducing that extra base_url check. And I fail to think of a situation where code explicitly sets $options['base_url'] for a frontend path, that path must still be subject to automatic rewriting.

Solution

The above leads to the following code change in LupusFrontendPathProcessor:

-    if (isset($options['route']) && in_array($options['route']->getPath(), $this->frontendPaths) && $request) {
+    if (isset($options['route']) && in_array($options['route']->getPath(), $this->frontendPaths)
+      && empty($options['lupus_decoupled_skip_rewrite']) && empty($options['base_url']) && $request) {

with 'lupus_decoupled_skip_rewrite' set only in BaseUrlProvider::getAdminBaseUrl(). (The "View API output" links already set 'base_url').

πŸ› Bug report
Status

Fixed

Version

1.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States glynster

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @glynster
  • First commit to issue fork.
  • Status changed to Needs work 4 months ago
  • πŸ‡³πŸ‡±Netherlands roderik Amsterdam,NL / Budapest,HU

    Thanks. The first commit is a test, which is now failing. Hopefully a fix follows soon.

  • πŸ‡³πŸ‡±Netherlands roderik Amsterdam,NL / Budapest,HU

    I feel like I'm taking a stab in the dark / retroactively establishing 'rules' for the rewriting of URLs, to fit whatever works.

    Well, a little tweak worked / at least passes all the tests: do not change the base URL if $options['base_url'] is already set.

    (We must still change things if $options['base_url'] is not set yet but $options['absolute'] is set to TRUE -- otherwise many things start failing.)

    I'll create a MR but won't set "Review" state before it has run through our internal test suite - and who knows what things that will trigger.

  • Pipeline finished with Success
    4 months ago
    Total: 193s
    #112131
  • Pipeline finished with Success
    4 months ago
    Total: 231s
    #112817
  • Pipeline finished with Success
    4 months ago
    Total: 193s
    #113110
  • Pipeline finished with Success
    4 months ago
    Total: 193s
    #113220
  • Status changed to Needs review 4 months ago
  • πŸ‡³πŸ‡±Netherlands roderik Amsterdam,NL / Budapest,HU

    The MR introduces a new URL option 'lupus_decoupled_skip_rewrite'. I want to state clearly why (even if only for my future self):

    • In a non-API request == backend HTML page, we need* to rewrite links to frontend destinations. In practice: we need the node-view links in /admin/content to point to the frontend.
    • We have no easy way to distinguish between these links, and a call to BaseUrlProvider::getAdminBaseUrl(), which must not be rewritten.
      • We used to distinguish between them by only rewriting links that had $option['entity'] set, but we also need to rewrite the following, for which it is practically impossible to always set $option['entity']:

    There is another solution that tiptoes around the above and passes all our current tests** + also fixes the "View API Output" links:

    -    if (isset($options['route']) && in_array($options['route']->getPath(), $this->frontendPaths) && $request) {
    +    if (isset($options['route']) && in_array($options['route']->getPath(), $this->frontendPaths) && empty($options['base_url']) && $request) {
           $absolute = $options['absolute'] ?? FALSE;
    -      if ($absolute || !$this->isApiResponse($request)) {
    +      if ($this->isApiResponse($request) ? $absolute : isset($options['entity'])) {
    

    As in:

    • For non-API responses, only rewrite links where isset($options['entity']); this is equal to the 2023 situation.
    • For API responses, only rewrite absolute links - .

    Apparently we don't currently need BaseUrlProvider::getAdminBaseUrl() in API responses - but this still feels fishy to me. It feels clearer to introduce a new URL option 'lupus_decoupled_skip_rewrite' option to prevent that (hopefully to be used only inside of BaseUrlProvider).

    For comparison, the current proposed code change is:

    -    if (isset($options['route']) && in_array($options['route']->getPath(), $this->frontendPaths) && $request) {
    +    if (isset($options['route']) && in_array($options['route']->getPath(), $this->frontendPaths)
    +      && empty($options['lupus_decoupled_skip_rewrite']) && empty($options['base_url']) && $request) {
    

    where && empty($options['base_url']) could also be left out and replaced by setting $options['lupus_decoupled_skip_rewrite'] explicitly for "View API output".

    --

    * I'm treating this "need" as a given: the code which rewrites links to frontend destinations has existed since Oct 2022. As far as I've been able to see, we could theoretically do without it, but that would mean

    • the frontend destination links not being visible in users' browsers in e.g. admin/content, which is arguably a UX degredation
    • extra redirects from the backend to the frontend destination, whenever such a link is clicked.
    • some code change needed in FrontendRedirectSubscriber; I haven't checked those details.

    ** I haven't checked our internal test suite with this yet.

  • πŸ‡³πŸ‡±Netherlands roderik Amsterdam,NL / Budapest,HU
  • πŸ‡³πŸ‡±Netherlands roderik Amsterdam,NL / Budapest,HU
  • πŸ‡³πŸ‡±Netherlands roderik Amsterdam,NL / Budapest,HU
  • πŸ‡³πŸ‡±Netherlands roderik Amsterdam,NL / Budapest,HU
  • Status changed to Needs work 4 months ago
  • πŸ‡¦πŸ‡ΉAustria fago Vienna

    thx. I think the analysis and changes make sense.

    Only think I think we should improve is the naming of the option "lupus_decoupled_skip_rewrite", because without knowing this issues, the name would not tell me what it is about. What rewrite? In the end, the flag is about to force the baseURL to the backend (or frontend?).

    What about supporting the flag 'lupus_decoupled_frontend' => FALSE or 'lupus_decoupled_rewrite_frontend' => FALSE ?

  • Pipeline finished with Success
    4 months ago
    Total: 194s
    #114559
  • Status changed to Needs review 4 months ago
  • πŸ‡³πŸ‡±Netherlands roderik Amsterdam,NL / Budapest,HU

    I have an in-grown reservation against parameters that are unset and default-TRUE ... but that doesn't matter much here because we don't actually want this one to be used much.

    Implemented as 'lupus_decoupled_rewrite_frontend' => FALSE. Tests are green.

  • Status changed to Fixed 4 months ago
  • πŸ‡¦πŸ‡ΉAustria fago Vienna

    > I have an in-grown reservation against parameters that are unset and default-TRUE ... but that doesn't matter much here because we don't actually want this one to be used much.

    :D I dislike parameters which have a negation in the naming.. ;-) We can bike-shed!

    Anyway, this is good to go, merged, thank you!

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.69.0 2024