Skip to content

ably-labs/fauna-ably-ecommerce

Repository files navigation

E-commerce demo using Ably and Fauna

This demo shows a way of getting realtime updates and interactions for customers on an e-commerce site. Users are able to login, browse items, buy them, and view their historical orders. This is done by using Fauna as a database to reliably store and query items, and Ably to reliably distribute data to clients in realtime over WebSockets.

Setup

We will need a Fauna and Ably account, and then we can start running this project locally.

Setup Fauna Account

Firstly, you will need a Fauna account, and to create a new Database. Populate it with the demo data by ticking the 'Use demo data' button during this process. Also ensure the region is 'Classic (C)'.

Screenshot 2022-08-09 at 12 57 01

If you choose to have the database in a specific region, you'll need to state this region in the .env file at the base of this directory. This will be either eu or us as the FAUNA_REGION value.

Once you have a database, create an API key for it with admin privilege by going to the 'Security' tab in the sidebar, and selecting '+ New key' in the new tab.

Screenshot 2022-08-09 at 12 59 24

Add this key to a .env file within the base of this directory, as FAUNADB_API_KEY.

Next, we need to create a new Index in Fauna, which we can use to ensure we don't get customers with duplicate usernames. Within the Fauna database's Shell tab, run the following query:

CreateIndex({
  name: "users_by_username",
  permissions: { read: "public"},
  source: Collection("users"),
  terms: [{field: ["data", "username"]}],
  unique: true,
})

In addition, we will need an Index to reflect all the Products, so we can use a stream to observe whenever there's a change. Run the following in the shell as well:

CreateIndex({
  name: "products_by_ts",
  source: Collection("products"),
  values: [{ field: "ts" }]
})

Finally, we will be creating an additional function in Fauna to allow us to make stock changes on items without risking dropping below 0 stock. This will be useful for simulating stock changing for customers, as though other customers were buying items and stock was coming back in.

In the Functions tab of Fauna, create a new function called increment_stock, and add the following code to it:

Query(
  Lambda(
    "products",
    Let(
      {
        products: Map(
          Var("products"),
          Lambda(
            "requestedProduct",
            Let(
              {
                product: Get(
                  Ref(
                    Collection("products"),
                    Select("productId", Var("requestedProduct"))
                  )
                )
              },
              {
                ref: Select("ref", Var("product")),
                currentQuantity: Select(["data", "quantity"], Var("product")),
                requestedQuantity: Select(["quantity"], Var("requestedProduct"))
              }
            )
          )
        )
      },
      Do(
        Foreach(
          Var("products"),
          Lambda(
            "product",
            If(
              LTE(
                Select("requestedQuantity", Var("product")),
                Select("currentQuantity", Var("product"))
              ),
              Var("product"),
              Abort(
                Concat([
                  "Stock quantity for Product [",
                  Select(["ref", "id"], Var("product")),
                  "] not enough – requested at [",
                  ToString(Time("now")),
                  "]"
                ])
              )
            )
          )
        ),
        Foreach(
          Var("products"),
          Lambda(
            "product",
            Update(Select("ref", Var("product")), {
              data: {
                quantity: Add(
                  Select("currentQuantity", Var("product")),
                  Select("requestedQuantity", Var("product"))
                )
              }
            })
          )
        )
      )
    )
  )
)

Setup Ably Account

Next, we need to set up an Ably account. Sign up for an Ably account if you don't have one, then go to the Ably App you intend to use for this.

Within the app, go to the API key tab, and copy the Default API key's value. Paste this into the .env file you created earlier, with the name ABLY_API_KEY.

Screenshot 2022-08-09 at 13 07 24

Finally, we need to create some Channel Rules, which will allow for the last message on a channel to be persisted for up to a year. This is useful for ensuring that data is always accessible to our customers. Within the Ably App, go to the 'Settings' tab, and go to the 'Channel Rules' section. Select 'Add new Rule', set the 'Namespace' to be 'app', and tick the 'Persist last message' box. Finally, click 'Create channel rule'.

Screenshot 2022-08-09 at 13 30 46

Running the app

With the config finished, it's time to get the app running. Firstly, run npm install to get the appropriate node modules. Once that's done, run:

npm run start

This will run the server. The server is an Express.js server. It is doing 2 things:

  • Hosting endpoints which can be used by clients for viewing the site, logging in, and authenticating with Ably
  • Running a connector between Ably and Fauna, allowing for certain bits of data to be accessible to customers

To view the site, simply go to localhost:3000.