"Phoenix Product Codex" updated: bundles/kits and product categories

“Phoenix Product Codex” updated: bundles/kits and product categories

06 June, 2025 4 min read
Elixir, Ecto, Phoenix, APIs, databases, book, SQLite, learning

Hello dear readers and API builders!

After a month-long pause, I bring you a new release of Phoenix Product Codex , v0.23.4. In this release:

  1. The concept of how we will/might approach bundles/kits of products in Chapter 1 has been reworked, as the previous explanation still leaned too much on the now-outdated concept of a split between sales items and product variants. With the new concept that we’ll pursue in the upcoming Chapter 7 (i.e., in 2 releases’ time, target by end of June), we are leaving the old concept of the Python-based ProductItems API behind for good, and rely on a purely relational model to deal with variants that themselves can be either component variants (“singles”, i.e. not bundles/kits) or “kit variants”, i.e. variants that themselves are made of other kit variants and/or component variants. The section has been reworked.

  2. The new Chapter 5 on modeling the categories table, the first table of the Taxonomy context, has been added. Here, we also implement custom validation functions for 3-character product-category codes using only characters from Crockford’s Base32 alphabet for reducing the probability of typos, and use the Jaro-Winkler string distance metric (with String.jaro_distance/2 ) to help API users prevent typos or duplication of %Category{} records. We also modify router.ex to convert the GET /api/categories/:id route to GET /api/categories/:identifier. This makes it possible for API consumers like a website to read category information by the category :code too, instead of only by the :id (which is only useful for admin purposes of Create, Update and Delete actions). The categories table was a simple one and the chapter is therefore quite short and punchy.

Some insights about the roadmap

In the upcoming release, we’ll return to the Supply context, where we’ll model the families table of the product families (that belong to product categories). There, due to the growing number of data that the GET /api/families route returns, we’ll start implementing a way to optionally paginate the returned list of results and perhaps also add HATEOAS -compatible link fields to the JSON response (prev/next/first/last), which will also make micro-frontends with htmx simpler to implement.

In the release after that one we’ll tackle the biggest chunk of functionality, the variants table for product variants (supplier-provided singles or kits, or our business’ bundles/kits) and its companion kit_compositions table that will tackle the bundling/kitting functionality. I expect that this will be a pretty long chapter, as we need to also write validation functions that prevent self-references and circular references within the “bundle recipes”. Latest by that point, we’ll also start working on caching database query results with a GenServer and then with cachex , to keep the API performant even with thousands of %Variant{} records in the database.

After the entire ERD will have been implemented together with the business logic (if it makes sense, perhaps even parallel to that), we’ll start adding the rest of the nice-to-have features in the “Coming Soon / Eventually” section; most importantly, authentication with Bearer tokens to prevent data such as list prices and supplier discounts from leaking to specific consumers (e.g. a website), API rate limiting with Hammer , filtering and sorting for the :index action of all endpoints, and tags that can be applied to entire product families and to variants, for example so that the API can provide data usable by a frontend implementing facet search.

There’s plenty more to come, since we also need to associate all relevant records with Ecto’s has_many/belongs_to and provide nested routes like what we did for /api/suppliers/:id/brands and /api/brands/:id/supplier, so I’m marking the book as a tentative 23% complete for now. However, now that my work on Breek.gr has let off a bit after releasing a major upgrade, I can focus on Phoenix Product Codex once again.