clock menu more-arrow no yes

Super Magic Component Stitching Wonder Proxy

This is an otherwise normal Chorus story. It is composed in the Anthem Story editor and rendered by Chorus/Unison.

However, if you Click Here the page will be rendered with this text and the placeholders below replaced with Components...

Click Here

Component Placeholder Text

Component Placeholder Text

Wait, what?

Ok, So How does this work?

Here are some boxes and arrows:

Duet Proxy Service Diagram

Intriguing! Tell me more!

Duet Proxy is a super fast proxy written in Rust and deployed as a Fastly Service via Fastly’s Compute@Edge platform.

Duet Proxy is a super fast proxy written in Rust and deployed as a Fastly Service via Fastly’s Compute@Edge platform. As the diagram describes it intercepts requests to Chorus (or any other site that it is deployed in front of) and inserts the components that have been programmed for that site and page in Amphora. Recall that at its core Amphora is a framework for managing components and composing pages from components. It is “Api Driven”, meaning you can create, update and delete component instances and pages via the Api. And, you fetch all the data for pages and components via an Api.

The Amphora Api response is a simple, it looks something like this:



{
  "top":[
    {
      _ref:"_component/a",
      data:{...},
      html:"<div>Hello World</div>"
    },
    {
      _ref:"_component/b",
      data:{...},
      html:"<div>Goodbye World</div>"
    }
  ]
}

This data means “the following components should be rendered in the component list named ‘top’”

Putting it all together: A request hits the Duet Proxy service on Fastly. Just like any other Fastly service Duet Proxy proxies the request to Chorus. However, Duet Proxy also (and in parallel) requests data for the page from the Amphora Api. Both requests are made through the Fastly Cache. Upon receiving the responses from Chorus and Amphora Api, Duet Proxy streams the Chorus html response through a fast HTML Rewriter. Given the example data above the HTML Rewriter is configured to look for a <component-list> tag with the list=’top’ attribute. e.g. <component-list list=’top’></component>. If it finds this tag in the Chorus html response then it replaces the contents of that tag with the concatenated html from the Amphora Api data. Voila! We have dynamically inserted components into a Chorus page!

Possibly Asked Questions:

This story is running on production Chorus; did you deploy any code to Chorus to make this work?

No! I made use the HTML Block feature in the Anthem story editor to insert <component-list /> tags into the story body. This turned out to be pretty handy because I could insert default content that appears if the component list is not replaced. See below:

Here, is an example of the the Duet Proxy rendering components on a Group page.

What happens if the response from Chorus has no <component-list> tags, or no <component-list> tags with list attributes that match the Amphora Api data?

Nothing! Nothing is replaced and the browser will receive and render whatever markup Chorus produced. Given this, Chorus can always deliver default markup with the a <component-list> tag; or nothing at all!

It looks like two requests at minimum are made to render pages (one to Chorus and one to Amphora Api). How can this possibly be performant or robust?

Yes, it is true that for uncached responses two requests are made. But those two requests can be fulfilled very quickly and very robustly for several reasons. First, the requests to Chorus and to Amphora Api are made in parallel through the Fastly cache. Given that requests are made through the Fastly Cache responses from Amphora Api and Chorus can be cached as usual by Fastly, expired via purges, managed via Surrogate-Control and Surrogate-Key headers, etc. Additionally, stale-if-error and stale-while-revalidate patterns still apply, so in the case of either backend being down, responses can be served from cache.

What about customizing responses for each user?

A great thing about this content stitching happening at the edge is that Duet Proxy is transparent to Chorus and the Amphora Api and therefore each backend request can have full access to all cookies. Chorus responds to the request as usual. And if we choose, the Amphora-Api can customize components based on session data as well.

What does this mean for the Duet and the effort to build a new audience experience framework?

The Duet Proxy Service is a means by which Components can be stitched onto a page. It proposes no solution for how components are made, how components are styled, how can pages should be composed of components, how a design system fits into anything, etc. It is true that this demo leverages Amphora which is a part of Clay; and it is true that Amphora is really well suited for the task of rendering components and composing components into pages; but there is nothing about the way Duet Proxy works that is dependent on Amphora. Any system for server side rendering components will suffice. What Duet Proxy does provide is a means for incrementally adding new audience experience components to existing pages with very little lift required on the Chorus or NYMag/Clay side. Adding areas of the page that can be replaced by components is as simple as wrapping them in <component-list> tags.

Further Reading