Skip to content

1. End‐to‐End Flow

Tanju Erinmez edited this page Apr 27, 2025 · 30 revisions

Today's Battle-Tested Crosswalk Flow in Production

fstab mountpoint url:

mountpoints:
  /:
    url: "https://author-p130360-e1272151.adobeaemcloud.com/bin/franklin.delivery/adobe-rnd/aem-boilerplate-xwalk/main"
    type: "markup"
    suffix: ".html"

publishBaseUrl:

https://main--aem-boilerplate-xwalk--adobe-rnd.aem.live
sequenceDiagram
    actor author as Author
    participant helix as Edge Delivery Services
    box lightslategray: <br/>author-p{programId}-e{envId}.adobeaemcloud.com
      participant aem as AEM Author Instance<br/>(JVM)
    end

    author ->> aem: presses "Publish"
    activate aem
    aem -->> author: "acknowledged"
    aem ->> helix: publish
    deactivate aem
    activate helix
    author ->> helix: GET {publishBaseUrl}/articles/article-1
    helix -->> author: returns "current HTML"

    rect rgba(200, 200, 255, 0.3)
        Note right of aem: This is the focus of the Hackathon.
        helix ->> aem: GET {fstab mountpoint url}/articles/article-1
        activate aem
        aem -->> helix: returns HTML
        deactivate aem
    end

    helix ->> helix: publishes new HTML
    deactivate helix

    author ->> helix: GET {publishBaseUrl}/articles/article-1
    activate helix
    helix -->> author: returns "new HTML"
    deactivate helix
Loading
AEM (Java‑based)
Pros Cons (solve it in Hackathon?)
  • Highly stable & secure, regenerates IMS Access Token every 23h
  • Superb caching of JCR nodes, permits to render and serve HTML efficiently to Helix
  • Very fast from pressing Publish to appearing on live in ~3s
  • While AEM provides Java APIs, its HTTP-accessible APIs primarily operate directly on the underlying JCR data model, not higher-level abstractions. This often necessitates developing new features within the OSGi environment to leverage existing Java abstractions effectively.
  • Deploying a developed feature to the live AEM Cloud instances typically takes several weeks from completion to availability.
  • Conducting experiments with specific customers (e.g., for a VIP Project) requires creating a private release. However, the customer must then be opted out of the standard daily update cycle to prevent the experimental release from being overwritten. This process is not sustainable for managing larger-scale customer previews or alpha testing programs.

In Hackathon Implemented Flow

Approach:

  • Route the traffic to a Worker that knows the XWalk specifics
  • Use the new Content API as the Abstraction Layer (AEM Pages vs. JCR Data)
  • Implement the Content API as a Service (Cloudflare Worker) too, to benefit from the rapid feature development cycle

fstab mountpoint url:

mountpoints:
  /:
    url: "https://xwalk-renderer-poc.adobeaem.workers.dev/xwalkpages/p130360_e1272151_1534567d-9937-4e40-85ff-369a8ed45367/main"
    type: "markup"

publishBaseUrl:

https://main--te-sites-content-api-poc--terinmez.aem.live/
sequenceDiagram
    actor author as Author
    participant helix as Edge Delivery Services
    participant xwalk as XWalk Renderer (Cloudflare)
    box lightslategray: <br/>author-p{programId}-e{envId}.adobeaemcloud.com
      participant pages as /adobe/pages Service (Cloudflare)
      participant aem as AEM Author Instance<br/>(JVM)
    end
    
    author ->> aem: presses "Publish"
    activate aem
    aem -->> author: "acknowledged"
    aem ->> helix: publish
    activate helix
    helix -->> aem: "acknowledged"
    deactivate aem    
    helix ->> xwalk: GET {fstab mountpoint url}/articles/article-1
    activate xwalk
      author ->> helix: GET {publishBaseUrl}/articles/article-1
      helix -->> author: returns "current HTML"
      xwalk ->> pages: GET /pages/byUrl?url=`{fstab mountpoint url}/articles/article-1`
      activate pages
        pages ->> pages: 1️⃣ determineAemSiteNameBySiteId(), unless cached
        activate pages
          pages ->> aem: /bin/querybuilder.json
          activate aem
            aem -->> pages: returns /conf/{aemSiteName}/ in jcr:path (JSON)
          deactivate aem
          pages -->> pages: returns aemSiteName
        deactivate pages
        pages ->> pages: 2️⃣ determinePageInfoByAemSiteNameAndPagePath()
        activate pages
          pages ->> aem: /bin/querybuilder.json
          activate aem
            aem -->> pages: returns JCR Node Hits (JSON)
          deactivate aem
          pages -->> pages: returns pageId, siteId, parentPageId ...
        deactivate pages
        pages -->> xwalk: returns page data with pageId (JSON)
      deactivate pages
      xwalk ->> pages: GET /pages/{pageId}/content
      activate pages
        pages ->> aem: GET /_jcr_id/{pageId}.6.json
        activate aem
          aem -->> pages: returns JCR Nodes (JSON)
        deactivate aem
        pages ->> pages: json2html()
        pages -->> xwalk: return page content (HTML)
      deactivate pages
      xwalk -->> helix: returns HTML
    deactivate xwalk
    deactivate helix

    author ->> helix: GET {publishBaseUrl}/articles/article-1
    activate helix
    helix -->> author: returns "new HTML"
    deactivate helix

Loading
Cloudflare Workers (Javascript‑based)
Pros Cons (solveable?)
  • Kept the data management in the highly stable and secure AEM instance
  • Leveraged the standard exposed JCR HTTP APIs, without deploying any code to AEM
  • Kept it still very fast from pressing Publish to appearing on live in ~3s
  • Multiple roundtrips needed via the JCR HTTP-based APIs, which makes it a chatty solution
  • The returned JSONs are large and contain unnecessary node siblings (consequence of json fetch)
  • The first Worker basically only needs to translate the URL because Helix cannot handle query parameters

Suggested Future Flow

Approach:

  • enrich the Content API in such a way, that the Helix to Content API translation is not needed anymore
  • Implement the Content API on the AEM Instance in such a way, that the Content Tree is logically exposed as JSON and read/write roundtrips are made possible
  • For new functionality use the API Router flexibility to prototype new Content API endpoints in a Cloudflare Worker first, such as rendering the HTML in Javascript in a Worker, before Implementing them in Java.

fstab mountpoint url:

mountpoints:
  /:
    url: "https://author-p130360-e1272151.adobeaemcloud.com/adobe/sites/1534567d-9937-4e40-85ff-369a8ed45367/contentByPath"
    type: "markup"
sequenceDiagram
    actor author as Author
    participant helix as Edge Delivery Services
    box lightslategray: <br/>author-p{programId}-e{envId}.adobeaemcloud.com
      participant pages as /adobe/pages Service (Cloudflare)
      participant aem as AEM Author with Content API<br/>Instance (JVM)
    end
    
    author ->> aem: presses "Publish"
    activate aem
    aem -->> author: "acknowledged"
    aem ->> helix: publish
    activate helix
    helix -->> aem: "acknowledged"
    deactivate aem    
    helix ->> aem: GET {fstab mountpoint url}/articles/article-1
    activate aem
    aem -->> helix: 303 See other Location: /adobe/pages/<article-1 pageId>
    deactivate aem
    author ->> helix: GET {publishBaseUrl}/articles/article-1
    helix -->> author: returns "current HTML"
    helix ->> pages: GET text/html /adobe/pages/<article-1 pageId>  
    activate pages
    pages ->> aem: GET /adobe/pages/<article-1 pageId>/content  
    activate aem
    aem -->> pages: returns Content API Content Tree as JSON
    deactivate aem
    pages ->> pages: contentTreeJson to HTML
    activate pages
    pages -->> pages: returns HTML
    deactivate pages
    pages -->> helix: returns HTML
    deactivate pages
    deactivate helix

    author ->> helix: GET {publishBaseUrl}/articles/article-1
    activate helix
    helix -->> author: returns "new HTML"
    deactivate helix

Loading

Clone this wiki locally