github icon

github icon

Complete Mutation

May 17, 2020


Now we are going to complete the mutation. First off let's install some packages:

$ yarn add uuid stripe

uuid is used to generate random UUID's for the bookingId. Since DynamoDB is a NoSQL datastore it does not auto-generate IDs like a SQL datastore.

stripe will allow us to interact with the stripe API.

Next lets go into our makeABooking mutation and add the following:

import { v1 as uuidv1 } from "uuid"
import stripePackage from "stripe"
import * as dynamoDBLib from "../../libs/dynamodb-lib"

export const makeABooking = async (args, context) => {
  //Get the listing that the user selected
  //from the client
  const getPrices = async () => {
    const params = {
      TableName: process.env.ListingsDB || "dev-listings",
      KeyConditionExpression: "listingId = :listingId",
      ExpressionAttributeValues: {
        ":listingId": args.listingId,
      },
    }
    try {
      const listings = await dynamoDBLib.call("query", params)
      return listings
    } catch (e) {
      return e
    }
  }
}

⌛ First off we are adding our necessary libs to the file

⌛ Then we are creating a function called getPrices that will go into the listings table and get the listing that matches the listingId for the listing the customer wants to make a booking for.

Next up let's calculate the price of the booking:

//set the listing to a variables so we can resuse it
const listingObject = await getPrices()

//caLCULATE THE amount to be charged to the
//customers card

const bookingCharge = parseInt(listingObject.Items[0].price) * args.size
//get the name of the listing

const listingName = listingObject.listingName
//create an instance of the stripe lib

const stripe = stripePackage(process.env.stripeSecretKey)

//charge the users card

const stripeResult = await stripe.charges.create({
  source: "tok_visa",
  amount: bookingCharge,
  description: `Charge for booking of listing ${args.listingId}`,
  currency: "usd",
})

⌛ First, we call the function to get the price of the listing

⌛ then we get the total by getting the price of the listing and then multipling it by the amount of travelers on the trip.

⌛ next we create an instance of the stripe library

⌛ then we create a charge to the customers card.

Next up we can create the params to send to DynamoDB:

//create the booking in the table
const params = {
  TableName: process.env.BookingsDB,
  Item: {
    bookingId: uuidv1(),
    listingId: args.listingId,
    bookingDate: args.bookingDate,
    size: args.size,
    bookingTotal: bookingCharge,
    customerEmail: args.customerEmail,
    customers: args.customers,
    createdTimestamp: Date.now(),
    chargeReciept: stripeResult.receipt_url,
    paymentDetails: stripeResult.payment_method_details,
  },
}

⌛ As before we are simply creating a params object that has the necessary TableName, and the fields that match the Booking Type in the schema. We have added a createdTimestamp and paymentDetails fields for internal use that will not be exposed to the API.

Next let's send the params to DynamoDB:

try {
  //insert the booking into the table
  await dynamoDBLib.call("put", params)

  return {
    bookingId: params.Item.bookingId,
    listingId: params.Item.listingId,
    bookingDate: params.Item.bookingDate,
    size: params.Item.size,
    bookingTotal: params.Item.bookingTotal,
    customerEmail: params.Item.customerEmail,
    customers: params.Item.customers.map(c => ({
      name: c.name,
      Surname: c.Surname,
      country: c.country,
      passportNumber: c.passportNumber,
      physioScore: c.physioScore,
    })),
    chargeReciept: params.Item.chargeReciept,
  }
} catch (e) {
  return e
}

⌛ We are simply doing a put action to DynamoDB to insert the mutation into the table.

⌛ Then we are returning the Booking object back to the API.

⌛ In the customers section we are simply mapping over the customers supplied.

Next let's test the function with the follow mutation:

mutation{
  makeABooking(listingId:"a114dded-ddef-4052-a106-bb18b94e6b51",bookingDate:"20-May-30",
    customerEmail:"peter@gmail.com",customers:{name: "Peter",surname:"Griffin",physioScore:"0",country:"USA",passportNumber:"34343445"}){
    chargeReciept
    bookingId
    size
  }
}

If all went well our mutation should match the screenshot below:

muatuion-screenshot

Now our mutation is working. Now we can write unit test for functions.

Chapters

Backend

Frontend