Problem/Motivation

breadcrumbs in CE API output have a URL pointing to the backend.

See screenshot, or test-fail MR whose phpunit test outputs

There was 1 failure:

1) Drupal\Tests\lupus_decoupled\Functional\LupusDecoupledApiResponseTest::testSchemaBreadcrumbs
Breadcrumb 0 must start with the frontend base URL.
Failed asserting that 'https://lupus-decoupled.ddev.site:8443/' starts with "https://lupus-nuxt.ddev.site:8443".

Steps to reproduce

  • Enable lupus_decoupled_schema_metatag module (or only schema_metatag module; the only difference is in where exactly the breadcrumbs are visible.)
  • In configuration - metatag - any node type: Edit settings "Schema.org: WebPage - breadcrumbs", set to Yes
  • View API output of corresponding node

Proposed resolution

Discussed:

LupusFrontendPathProcessor::processOutbound() currently only changes URLs that have a (configured) front end path, if these have a 'entity' option.

Instead: always change URLs that have a (configured) front end path. If they don't have a 'entity' option, then change them to the 'default' front end base URL.

Complications with this resolution

Dropping the restriction on $options['entity'] has the effect that several other kinds of links are having the frontend URL appended. Often this is unnecessary. To fix this, $request->getRequestFormat() != 'custom_elements') was basically changed to $request->getRequestFormat() != 'custom_elements') && !$request->attributes->get('lupus_ce_renderer', FALSE) while reviewing this issue.

NOTE - behavior change

The lupus_decoupled_ce_api.frontend_paths services parameter has "/" added. This is necessary for making the breadcrumb links to 'home' in the ld+json payload point to the frontend (not the backend -- they are always absolute).

This has an added effect of making "Home" links on the backend also point to the frontend homepage. They pointed to the backend before.

We basically cannot distinguish one from the other, without adding extra logic.

Complications with this resolution - obsolete comments:

1)The original restriction was;

if ($absolute || $request->getRequestFormat() != 'custom_elements') {
  change to an absolute link pointing to frontend

2)This evolved to;

if ($absolute || !in_array($request->getRequestFormat(), [NULL, 'json', 'custom_elements'], TRUE)) {
  change to an absolute link pointing to frontend

... it's likely fairly obvious that the 'json' format should be exempted from this. But the NULL format is also necessary if we want to prevent redirects specifically implemented through the Redirect module in API output, to be changed from relative to absolute unnecessarily. (Because the redirect module intercepts the REQUEST event, before the lupus_ce_renderer module sets the request format.)

(I'm trying to write a phpunit test to include here, to enforce that links handled by the Redirect module will stay relative. However I'm having some issues with that at the moment.)

3)I am experimenting with instead doing

if ($absolute || !$request->attributes->get('lupus_ce_renderer', FALSE)) {
  change to an absolute link pointing to frontend

Because frankly, it looks more straightforward to me... and it also solves another issue in our internal product.

Some of our internal tests are still failing, but it looks like that might mean our internal code should change instead. To be continued.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

roderik created an issue. See original summary.

roderik’s picture

Assigned: Unassigned » roderik
Issue summary: View changes
Status: Active » Needs work

The test-failure fails in the wrong way. Something about getFrontendBaseUrl() returning an empty string?

No biggie -- but interesting, because I hadn't discovered while writing the test for #3412044: 'alternate' link metatags do not point the frontend. Testing once more just to be sure, b.efore I actually push a fixed test (and a fix shortly after).

roderik’s picture

Assigned: roderik » Unassigned
Status: Needs work » Needs review
roderik’s picture

StatusFileSize
new6.08 KB

Patch file for use by other system

roderik’s picture

This seems to need more changes. Will specify later.

roderik’s picture

Assigned: Unassigned » roderik
Status: Needs review » Needs work
StatusFileSize
new7.52 KB

Menu items changed. Patch for test uploaded here; will update MR after test.

roderik’s picture

StatusFileSize
new2.52 KB
roderik’s picture

roderik’s picture

StatusFileSize
new7.56 KB

Previous one worked.

Trying to do some test runs on an alternative, though.

roderik’s picture

StatusFileSize
new2.57 KB
roderik’s picture

Issue summary: View changes

Updated my current changes in the summary.

fago’s picture

The proposed resolution
> If they don't have a 'entity' option, then change them to the 'default' front end base URL.
sounds good.

But, I don't think we should touch that part:

if ($absolute || $request->getRequestFormat() != 'custom_elements') {

Generally, I think this check is correct and should not be changed. Yes, maybe there are special-cases when we don't want it to happen, but then we should work them out individually, without touching that general check/logic. That's quite foundational and I don't think we should alter this check now - we want to stabilize and release.

if ($absolute || !$request->attributes->get('lupus_ce_renderer', FALSE)) {
Well, the code tries to determine API-responses, but it might be not 100% right in doing that.

https://git.drupalcode.org/project/lupus_decoupled/-/blob/1.x/modules/lu... is checking for both, what seems correct. Maybe just checking $request->attributes->get('lupus_ce_renderer', FALSE) would be enough, but I'm not sure about that, so that would have to be validated first.

> (I'm trying to write a phpunit test to include here, to enforce that links handled by the Redirect module will stay relative. However I'm having some issues with that at the moment.)

That would be a good improvement, but when hard it might better done as follow-up or added as acceptance-test. The other test-coverage improvemetns seem great already!

But the NULL format is also necessary if we want to prevent redirects specifically implemented through the Redirect module in API output, to be changed from relative to absolute unnecessarily. (Because the redirect module intercepts the REQUEST event, before the lupus_ce_renderer module sets the request format.)

I see. Could we make lupus_ce_renderer module to come earlier? Else, I guess we could simply check for both, to also catch those edge-cases, and call it a day.

roderik’s picture

StatusFileSize
new3.03 KB

Testing. Proper reply will come later.

roderik’s picture

StatusFileSize
new4.18 KB
roderik’s picture

Issue summary: View changes
Status: Needs work » Needs review

Thanks for the review and code pointer. I think I can boil it down by just responding to the last sentence:

I see. Could we make lupus_ce_renderer module to come earlier? Else, I guess we could simply check for both, to also catch those edge-cases, and call it a day.

For completeness: Making lupus_ce_renderer module to come earlier wouldn't solve the issue of the "relative" menu links in the menu API output being turned absolute. (They are requestformat "json" not ''custom_elements''.)

I think checking for both is good, and given your pointer to other code that already does this... this 'unifies' our code, which makes me feel safer. (I abstracted it into a protected function isApiResponse() too, for some added clarity. I now also see some other custom code exactly the same check.)

So, changes since your last comment:

  • add
      protected function isApiResponse(Request $request): bool {
        return $request->attributes->get('lupus_ce_renderer') || $request->getRequestFormat() == 'custom_elements';
      }
    
  • fix: add $options['entity'] to URLs used for the responsive iframe -- to fix cases where custom code overrides the base URL based on $options['entity']
roderik’s picture

Issue summary: View changes

Oh also:

Noted behavior change in the issue summary.

  • fago committed 0c5a020a on 1.x authored by roderik
    Issue #3414438 by roderik, fago: Fix 'breadcrumb' metatags do not point...
fago’s picture

Status: Needs review » Fixed

thank you, that looks great! I've slightly improved the comments in the service yml config and merged it.

glynster’s picture

StatusFileSize
new339.45 KB

Could this have introduced an issue with the View API Output links? At this point anytime we review the API we are redirected to the Nuxt app. Probably a small case missed perhaps?

glynster’s picture

Confirmed as soon as we revert to beta4 the urls for the API are corrected.

fago’s picture

ouch, yes I can reproduce the problem with gitpod. The API output points to the frontend, e.g. https://3000-drunomics-lupusdecouple-c470nu6nvfj.ws-eu108.gitpod.io/node... .. -> let's open a dedicated bug for this please!

Strange, that this did not occur in our setup, our complete integration test suite ran through without issues.

glynster’s picture

Done, added as a new bug.

Status: Fixed » Closed (fixed)

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