Introduction to Metaprogramming

The post belongs to NectarCommerce and Extension Framework Awareness

  1. NectarCommerce Vision
  2. Extension Framework Game Plan
  3. Introduction to Metaprogramming
  4. Ecto Model Schema Extension
  5. Ecto Model Support Functions Extension
  6. Phoenix Router Extension
  7. Phoenix View Extension
  8. Running Multiple Elixir Apps Together
  9. Extension Approach Explained
  10. Learning from failures: First Experiment at NectarCommerce Extension Approach
  11. Developing NectarCommerce Extensions
  12. Building an exrm release including NectarCommerce

What will be NectarCommerce

Off-the-shelf Opensource E-commerce application for building an online store.

Provides an Extension Framework to support features not included in core as extensions.

Strives for unobtrusive parallel development of NectarCommerce and Extensions

NectarCommerce is committed to providing a ready-to-use e-commerce solution but the definition of 100% is different under different business domains. It aims to solve common use-cases as part of the project and relying on extension framework to tap the rest.

Metaprogramming in Elixir

Note: If you are already familiar and experienced with Elixir Metaprogramming, you can jump to last section as it lists Metaprogramming resources
and constructs used in upcoming blogs when creating different extension DSL’s.

Elixir docs are excellent resources to get familiar with Metaprogramming:

Check out Understanding Elixir Macros blog series by @sasajuric

Book Metaprogramming Elixir by @chris_mccord is next step for diving deeper into metaprogramming.

Why another tutorial on an already well-documented metaprogramming topic ?

To revise and refresh something that we would refer time and again when reviewing Model, Router, View extension DSLs

Extension DSLs will be using below constructs to get the job done :)

  • Module.register_attribute/3
    • Registers an attribute. By registering an attribute, a developer is able to customize how Elixir will store and accumulate the attribute values.
  • Module.put_attribute/3
    • Puts an Erlang attribute to the given module with the given key and value
  • @before_compile
    • A hook __before_compile__/1 that will be invoked before the module is compiled
    • It allows us to inject code into the module when its definition is complete
  • __using__ hook
    • Checkout the title Examples for the usage & context and Best practices in link above
    • use ModuleName looks and invokes __using__ macro defined in ModuleName module
  • bind_quoted
    • Find the documentation under title Options for bind_quoted option in the link above
    • By using bind_quoted, we can automatically disable unquoting while still injecting the desired variables into the tree
  • Code.ensure_loaded?/1
    • Ensures the given module is loaded
  • apply/3
    • Invokes the given function from module with the array of arguments args.
  • Macro.escape/1
    • Recursively escapes a value so it can be inserted into a syntax tree

Metaprogramming pattern as used across extensions

Minimum three parts are needed to create & use an extension effectively:

  • Library Code
  • Service Code
  • Consumer Code

An extension and its use with Nectar can be viewed as Producer / Consumer relationship bound by a communication protocol.

Extension which wants to add a route, say a list of favorites, is a Producer (Service Code).

Nectar Router is a Consumer (Consumer Code) allowing the route additions through a communication protocol (Library Code)

  • Library code defines a macro providing a DSL, say define_route
  • Collect all definitions provided using DSL from Service code in Module attribute, say defined_routes
  • Library code defines a before_compile hook to add a macro extracting all collected definitions from module attribute, as module attributes are cleaned up as compilation completes
  • Inject generated code into targeting module Consumer code through __using__ hook as invoked by use ModuleWithDSLImplementation, say use ExtensionsManager.RouterExtension

Our aim with these posts is to start a dialog with the Elixir community on validity and technical soundness of our approach. We would really appreciate your feedback and reviews, and any ideas/suggestions/pull requests for improvements to our current implementation or entirely different and better way to do things to achieve the goals we have set out for NectarCommerce.

Enjoy the Elixir potion !!


Extension Framework Game Plan

The post belongs to NectarCommerce and Extension Framework Awareness Series

  1. NectarCommerce Vision
  2. Extension Framework Game Plan
  3. Introduction to Metaprogramming
  4. Ecto Model Schema Extension
  5. Ecto Model Support Functions Extension
  6. Phoenix Router Extension
  7. Phoenix View Extension
  8. Running Multiple Elixir Apps Together
  9. Extension Approach Explained
  10. Learning from failures: First Experiment at NectarCommerce Extension Approach
  11. Developing NectarCommerce Extensions
  12. Building an exrm release including NectarCommerce

What will be NectarCommerce

Off-the-shelf Opensource E-commerce application for building an online store.

Provides an Extension Framework to support features not included in core as extensions.

Strives for unobtrusive parallel development of NectarCommerce and Extensions

NectarCommerce is committed to providing a ready-to-use e-commerce solution but the definition of 100% is different under different business domains. It aims to solve common use-cases as part of the project and relying on extension framework to tap the rest.

Extension Framework Game Plan

Let’s validate and list the capabilities needed in Extension Framework through an extension which provides feature to mark a product as user’s favorite.

Favorite Product Extension Requirements:

  • Ability to mark and unmark a Product as favorite
    • a View probably showing all products with Ability to mark/unmark product as favorite
    • a controller action preparing the view
    • a route exposing the controller / view through Web
    • a controller action handling mark product as favorite
    • a route exposing the controller / view through Web
    • a controller action removing product from the list of favorites
    • a route exposing the controller / view through Web
    • a model interfacing with database to store product favorited by user
    • a migration to create join table in database
    • a join table storing product_id and user_id
  • Showing All Products favorited by a User
    • association in User to get favorite products
    • a View showing list of Favorite Products
    • a controller preparing the view
    • a route exposing the controller / view through Web
  • Showing Users who favorited a particular Product
    • association in Product to get users who favorited
    • a View showing list of Users who favorited
    • a controller preparing the view
    • a Route exposing the controller / view through Web
  • Ability to test the integration of above mentioned requirements

Let’s break the above requirements into two groups

  • Model layer changes
  • Request layer changes

Model Layer Changes

  • Ability to mark and unmark a Product as favorite
    • a model interfacing with database to store product favorited by user
    • a migration to create join table in database
    • a join table storing product_id and user_id
  • Showing All Products favorited by a User
    • association in User to get favorite products
  • Showing Users who favorited a particular Product
    • association in Product to get users who favorited

translates to

  • Ability to mark and unmark a Product as favorite
    • New Ecto Model with user_id and product_id fields
    • Ecto migration to create join table storing product_id and user_id
  • Showing All Products favorited by a User
    • extending User schema to have associations as needed
    • support functions in User Model to retrieve all products favorited by a user
  • Showing Users who favorited a particular Product
    • extending Product schema to have associations as needed
    • support functions in Product Model too retrieve all users who favorited a product

Request Layer Changes

  • Ability to mark and unmark a Product as favorite
    • a View probably showing all products with ability to mark/unmark product as favorite
    • a controller action preparing the view
    • a route exposing the controller / view through Web
    • a controller action handling mark product as favorite
    • a route exposing the controller / view through Web
    • a controller action removing product from the list of favorites
    • a route exposing the controllerontroller / view through Web
  • Showing All Products favorited by a User
    • a View showing list of Products
    • a controller preparing the view
    • already route exposing the controller / view through Web
  • Showing Users who favorited a particular Product
    • a View showing list of Users
    • a controller preparing the view
    • a route exposing the controller / view through Web

translates to

  • Ability to mark and unmark a Product as favorite
    • a View probably showing all products with ability to mark/unmark product as favorite
    • a controller with index / create / delete action
    • a route exposingposing index / create / delete action
  • Showing All Products favorited by a User
    • a View showing list of Products
    • a controller preparing the viewew
    • a route exposing the controller / view through Web
  • Showing Users who favorited a particular Product
    • a View showing list of Users
    • a controller preparing the view
    • a route exposing throughe controller / view through Web

What we need

  • way to extend schema definitions for existing models
  • way to add new functions in existing models
  • way to add routes
  • way to add controller / views for newly added routes
  • way to extend views
  • way to reuse layouts
  • way to reuse already available routes

How we attempt to solve

  • Elixir Metaprogramming
  • Elixir umbrella app dependencies to share and reuse code among Nectar & Extensions using ExtensionManager
  • Extensions as Phoenix project leveraging NectarCommerce

Bridging the Gap

Next Posts would refer the Favorite Product Extension to help co-relate and reveal the challenges & solutions implemented to propose an Extension framework.

Our aim with these posts is to start a dialog with the Elixir community on validity and technical soundness of our approach. We would really appreciate your feedback and reviews, and any ideas/suggestions/pull requests for improvements to our current implementation or entirely different and better way to do things to achieve the goals we have set out for NectarCommerce.

We look forward for your support and feedback on twitter and github

Enjoy the Elixir potion !!


NectarCommerce Vision

The post belongs to NectarCommerce and Extension Framework Awareness Series

  1. NectarCommerce Vision
  2. Extension Framework Game Plan
  3. Introduction to Metaprogramming
  4. Ecto Model Schema Extension
  5. Ecto Model Support Functions Extension
  6. Phoenix Router Extension
  7. Phoenix View Extension
  8. Running Multiple Elixir Apps Together
  9. Extension Approach Explained
  10. Learning from failures: First Experiment at NectarCommerce Extension Approach
  11. Developing NectarCommerce Extensions
  12. Building an exrm release including NectarCommerce

What will be NectarCommerce

Off-the-shelf Opensource E-commerce application for building an online store.

Provides an Extension Framework to support features not included in core as extensions.

Strives for unobtrusive parallel development of NectarCommerce and Extensions

NectarCommerce is committed to providing a ready-to-use e-commerce solution but the definition of 100% is different under different business domains. It aims to solve common use-cases as part of the project and relying on extension framework to tap the rest.

Vision

E-commerce Framework with an extension methodology which allows easy integration of custom features unique to the domain.

NectarCommerce in a NutShell

NectarCommerce is an E-commerce Elixir/Phoenix Application which is currently having following features:

  • Product Management
  • Order Management
  • Basic Stock Management

Please check out the demo and README

NectarCommerce and Extensions

The project is in its early stages where NectarCommerce and extensions are residing side-by-side in Elixir umbrella app.

Our plan is to evolve where NectarCommerce and all other extensions will be mix projects/applications which may have web components via phoenix, which can be downloaded as hex packages.

Once ready, NectarCommerce should provide an Extension Framework, where custom features as needed per domain can be developed and integrated back to NectarCommerce with minimal effort and no noticeable impact on runtime performance

The extensions should seamlessly integrate via Extensions Framework with NectarCommerce such that changes in extensions will not demand a change in NectarCommerce and extensions can incrementally adapt to changes in NectarCommerce for better support, new features, and betterments.

NectarCommerce and extensions can be grown and developed in isolations, wherein, NectarCommerce is developed by one team and extensions probably by many different teams where no one team will own all the extensions and NectarCommerce.

Our aim with these posts is to start a dialog with the Elixir community on validity and technical soundness of our approach. We would really appreciate your feedback and reviews, and any ideas/suggestions/pull requests for improvements to our current implementation or entirely different and better way to do things to achieve the goals we have set out for NectarCommerce.

Enjoy the Elixir potion !!


Announcing NectarCommerce, Vinsol's Open Source Elixir/Phoenix Project

Elixir coupled with the Phoenix Framework provides one of the most powerful platforms for developing Web and Mobile Applications. It's capability of producing highly reliable fault-tolerant systems has attracted developers worldwide.

Vinsol is delighted to announce the release of it's open-source E-Commerce Phoenix Project, NectarCommerce

It's being developed with an intent to serve as an off-the-shelf and easily customizable e-commerce solution, harnessing the high concurrency and better throughput supported by Elixir/PhoenixFramework.

Source Code is available on Github

Live Demonstration

User Interface
Username: alice@example.com
Password: foobar

Admin Interface
Username: bob@example.com
Password: secured

You can follow the updates on Twitter @NectarCommerce.

Any suggestions, improvements or contributions are welcome.


Privacy Preference Center