3

So, I'm building an Ecommerce Api with Koajs and Koa router, and i'm now handling orders payment request, the thing is, before the actual paying, the status of my order model change to 'Waiting for payment', and it is at this point when my API changes the stock of my products.

What I thought is that when this happen, for my response to be faster, the product update could be done asynchronously, as maybe the request may need to process a lot of products updates, and the client can recieve a response and then just focus on paying while the products are updating. But, what if two people make the a request with the same product and while updating it enters in a conflict as the sum of two quantities exceeds the actual product stock? (the shoppingCart checks not to surpass the limits of product stock but once this is done it cant be changed)

For this may be better to just make the client wait and do the process with await? or there is a way that can handle this type of problems better?

My code looks somewhat like this:

router.post('api.orders.payment', '/:id/pay', async (ctx) => {
  const order = await ctx.orm.order.findByPk(ctx.params.id);
  order.status = 'Waiting for payment';
  await order.save({ fields: ['status', 'total'] });
  // Update all the products
  updateProducts(ctx, order);
  ctx.body = ctx.jsonSerializer('order', {
    attributes: ['status', 'total'],
    topLevelLinks: {
      self: `${ctx.origin}${ctx.router.url('api.orders.show', { id: order.id })}`,
    },
  }).serialize(order);

And the updateProduct function looks like this:

async function updateProducts(ctx, order) {
  const shoppingCart = await ctx.orm.orderProduct.findAll({ where: { orderId: order.id } });
  let product = null;
  shoppingCart.forEach(async (element) => {
    product = await ctx.orm.product.findByPk(element.productId);
    product.stock -= element.quantity;
    await product.save({ fields: ['stock'] });
  });
}

I'm using Sequelize, Koa, Koa-router, jsonserializer, and my product model has attributes "id, stock", my order model has attributes "id", "total", and OrderProduct that represents my cart model has attributes "orderId", "productId" and "quantity".

0 Answers0