I am playing with Moltin for my upcoming talk on the API Strategy conference and it generates all kinds of blog posts ideas.
Context
Moltin is the API-first (or I would even argue the API-only) commerce platform. A “new kid on the block”, a recent Y Combinator graduate with a little more than $2M in seed funding. My talk is about cognitive APIs and smarter apps and I will be using a conversational e-commerce chatbot as an example. I picked Moltin as my commerce backend because it’s ridiculously easy to get started with, requires no upfront setup, and seems to provide a simple and yet a rich API that covers all my scenarios. Plus, their free tier gives me 30,000 requests per month.
You can’t transact with a commerce platform if it doesn’t have a product catalog. Products have variants (e.g. a t-shirt can come in different sizes and different colors) and different commerce platforms approach setting up this hierarchy differently. In Moltin, you first create a main product. Then you add modifiers (in my case - color
and size
). And then you add variations for each modifier. Moltin will then create the actual variants matrix behind the scenes. If, for example, you add blue
, red
, and white
variations to the color
modifier and S
, M
, L
to the size
modifier, you will end up with a nine total variations (every size available in every color).
Moltin APIs
Moltin APIs are lean HTTP endpoints that understand application/x-www-form-urlencoded
and multipart/form-data
and return back JSON. The team also supplies lightweight wrappers for JavaScript
, Python
, and other languages. Here’s, for example, how the creation of a variation in JavaScript
looks like:
1 | const moltin = require('moltin')({ |
I am scripting the creation of the product catalog using Adventure Works as my sample dataset so I need to run a lot of these asynchronous callback style request in order. I do it with Promise
s:
1 | const addVariation = (productId, modifierId, value) => { |
And now I can chain all my actions with .then()
.
Problem
I faced an interesting challenge as I was creating the variations for my products. Here’s how I do it. First, I figure out what modifiers I need to create and then for each modifier I collect the values. The result looks something like this:
1 | const mods = [{ |
Now I can recursively .map()
this structure into an array of Promise
s each creating a required variation in Moltin:
1 | // somewhere on the chain |
“Looking good”, I thought, until I found out that creating all the variations asynchronously in no particular order and maybe even in parallel confuses the logic on the Moltin side that creates the product matrix (details).
Since I can’t trigger a matrix rebuild via the API, the solution was to sequence the variants creation.
Solution
Instead of just mapping the modifiers to a list of Promise
s running somewhat concurrently, I I needed to chain variants creation one after another. I also needed to collect all created variations into a list for the next step in the bigger chain.
Nested reduce
to the rescue. First, the addVariation
now keeps track of the results:
1 | const addVariation = (productId, modifierId, value, bag) => { |
And the Promie.all()
has to convert into a linear chain of promises each creating a single variation:
1 | // somewhere on the chain |
Works great but I feel like it can be cleaner with Rx. If you know how to convert this to observable
s and not explicitly manage the collection of created variants, please drop me a line. Thanks!