Adam Shaylor

Pollinate customizer platform

  • technical prototype
  • front-end architecture
  • query language and parser

Pollinate has been building product selectors and customizers for years. During my tenure there, we worked with Benchmade, Wilson and Yakima. We saw an opportunity to draw on patterns we discovered working for them to create a platform from which all our clients could benefit by smaller scopes and faster development times. The resulting query language and front-end middleware I designed and built powers Pollinate’s customizer work today.

Custom query language

The most complex aspect of product customization is rendering. Given the rapidly changing landscape of HTML Canvas, WebGL and server-side rendering, we chose not to abstract any of the rendering. This left us open to vary our rendering strategy per project.

Instead, our first objective was to eliminate logic duplication between JavaScript in the browser and C# on the server. Most of the logic in a product customizer is responsible for modeling the relationships between product features and customizations. Database schemas composed of primitive values alone weren’t sufficient to model these rules.

We explored hypermedia affordances and isomorphic JavaScript but were ultimately dissatisfied with both options. Hypermedia affordances are not intended to impose complex logic on an API but rather to document conceptual links between resource endpoints with fairly straightforward CRUD operations that are typical in most HTTP APIs.

The Wilson uniform customizers like the one in this video use a custom canvas based renderer, whereas the customizer we built for Benchmade uses D3. Some of Pollinate’s latest customizers use WebGL.

Isomorphic JavaScript would have required that we build most (if not all) of the back end with node. While our front-end team had some experience in node, it was limited to front-end build tools and stateless side projects. Our back-end team had much stronger experience with .NET. We also explored options for compiling C# into JavaScript but they weren’t mature enough at the time.

What eventually dictated our aproach to sharing logic was the way we structured the recipe data. After creating a prototype admin interface and concocting some mock recipes, I noticed that the recursive recipe data structure looked a lot like a DOM tree.

If we could write product feature queries with something akin to CSS selector strings, it would be both easy to learn, easy to maintain and efficient to transmit. Rules could be written and stored on the server in an SQL database and we could reason about them both there and in the browser.

I looked into JSONSelect but ruled it out for a couple of reasons. The first was a raft of unresolved issues and open pull reqests on Github. The second was the verbosity of the selectors. By designing a custom query language specifically for MTOC I was able to whittle down the average query string length by more than half.

After demonstrating examples of how such a query language might work to the team and establishing the conventions of the language, I used a railroad diagram generator to formally document it and wrote JavaScript parser as its canonical implementation.

An example of Pollinate’s custom query language selecting features in two variations of the same product.

JavaScript middleware

Once the back-end and admin interface were built and the basic requirements for rendering were established, we needed to connect the dots between them into a JavaScript middleware library that could manage the relationships between rules, states and state history.

Concerned about a trend in the front-end industry of throwing away frameworks every couple of years, I chose our JavaScript dependencies carefully. I was also keen to avoid state mutations at the view layer. I built the middleware around event bus called Postal.js, using it as a state container that receives requests to mutate via events and publishes the results of those mutations as events to subscribers.

A custom jacket from Eddie Bauer’s line of custom clothing, powered by Pollinate’s customizer platform.

Credits