Skip to content

azinch/temporal-ecommerce

Repository files navigation

temporal-ecommerce

Shopping Cart API implemented as a workflow in temporal:

1. Add/Remove cart items, Checkout the cart

2. After timeout sent email to a user to remind of the cart abandoned

3. Update email of the user

Instructions

To run the worker and server, you must set the STRIPE_PRIVATE_KEY, MAILGUN_DOMAIN, and MAILGUN_PRIVATE_KEY environment variables. You can set the values to "test", which will allow you to add and remove elements from your cart. But you won't be able to checkout or receive abandoned cart notifications if these values aren't set.

To run the worker, make sure you have a local instance of Temporal Server running (e.g. with docker-compose), then run:

env STRIPE_PRIVATE_KEY=stripe-key-here env MAILGUN_DOMAIN=mailgun-domain-here env MAILGUN_PRIVATE_KEY=mailgun-private-key-here go run worker/main.go

To run the API server, you must also set the PORT environment variable as follows.

env STRIPE_PRIVATE_KEY=stripe-key-here env MAILGUN_DOMAIN=mailgun-domain-here env MAILGUN_PRIVATE_KEY=mailgun-private-key-here env PORT=3001 go run api/main.go

Interacting with the API server via cURL

Here is a guide to the basic routes that you can see and what they expect:

# get items
curl http:https://localhost:3001/products

# response:
# {"products":[
    # {"Id":0,"Name":"iPhone 12 Pro","Description":"Test","Image":"https://images.unsplash.com/photo-1603921326210-6edd2d60ca68","Price":999},
    # {"Id":1,"Name":"iPhone 12","Description":"Test","Image":"https://images.unsplash.com/photo-1611472173362-3f53dbd65d80","Price":699},
    # {"Id":2,"Name":"iPhone SE","Description":"399","Image":"https://images.unsplash.com/photo-1529618160092-2f8ccc8e087b","Price":399},
    # {"Id":3,"Name":"iPhone 11","Description":"599","Image":"https://images.unsplash.com/photo-1574755393849-623942496936","Price":599}
# ]}

# create cart
curl -X POST http:https://localhost:3001/cart

# response:
# {"cart":{"Items":[],"Email":""},
#  "workflowID":"CART-1619483151"}

# add item
curl -X PUT -d '{"ProductId":3,"Quantity":1}' -H 'Content-Type: application/json' http:https://localhost:3001/cart/CART-1619483151/4a4436be-3307-42ea-a9ab-3b63f5520bee/add

# response: {"ok":1}

# get cart
curl http:https://localhost:3001/cart/CART-1619483151/4a4436be-3307-42ea-a9ab-3b63f5520bee

# response:
# {"Email":"","Items":[{"ProductId":3,"Quantity":1}]}

Interacting with the API server with Node.js

Below is a Node.js script that creates a new cart, adds/removes some items, and checks out.

'use strict';

const assert = require('assert');
const axios = require('axios');

void async function main() {
  let { data } = await axios.post('http:https://localhost:3001/cart');

  const { workflowID } = data;
  console.log(workflowID)

  await axios.put(`http:https://localhost:3001/cart/${workflowID}/add`, { ProductID: 1, Quantity: 2 });

  ({ data } = await axios.get(`http:https://localhost:3001/cart/${workflowID}`));
  console.log(data);
  assert.deepEqual(data.Items, [ { ProductId: 1, Quantity: 2 } ]);

  await axios.put(`http:https://localhost:3001/cart/${workflowID}/remove`, { ProductID: 1, Quantity: 1 });

  ({ data } = await axios.get(`http:https://localhost:3001/cart/${workflowID}`));
  console.log(data);
  assert.deepEqual(data.Items, [ { ProductId: 1, Quantity: 1 } ]);

  await axios.put(`http:https://localhost:3001/cart/${workflowID}/checkout`, { Email: '[email protected]' });

  ({ data } = await axios.get(`http:https://localhost:3001/cart/${workflowID}`));
  console.log(data);
}();

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages