1 minute read

AWS DynamoDB is a fully managed NoSQL database service provided by Amazon Web Services (AWS). It is designed to deliver fast and predictable performance with seamless scalability, making it suitable for various use cases, such as gaming, mobile applications, Internet of Things (IoT), web applications, and more.

Query all items in the partition by the partition key

export async function getUsers(
  companyId: string
): Promise<[User[], string, string]> {
  console.info(
    `usersRepository - getting users by the companyId: ${companyId} - ${tableName}`
  )

  const params = {
    TableName: tableName,
    KeyConditionExpression: 'companyId = :companyId',
    ExpressionAttributeValues: {
      ':companyId': {
        S: companyId,
      },
    },
  }

  try {
    const result = await ddbDocClient.send(new QueryCommand(params))
    if (!result.Items) {
      return [[] as User[], statusCodes.NOT_FOUND, 'users not found']
    }

    return [
      result.Items.map(item => unmarshall(item) as User),
      statusCodes.OK,
      '',
    ]
  } catch (error) {
    return [
      [] as User[],
      error.$metadata.httpStatusCode,
      (error as Error).message,
    ]
  }
}

QueryCommand return items as Recode<string, AttributeValue>. AttributeValue is an object that has the type of the data and the value of the data in this way

name: {
	'S': 'Jean'
}

To map it to a javascript object, we can use unmarshall function, which belongs to @aws-sdk/util-dynamodb. You need to install the package. For more information, refer to AWS SDK for JavaScript v3 unmarshall.

yarn add @aws-sdk/util-dynamodb

Query an item by GSI (Global Secondary Index)

Unfortunately, you can’t use GetItemCommand if the key is GSI. Only QueryCommand supports index.

export async function getUser(email: string): Promise<[User, string, string]> {
  console.info(
    `usersRepository - getting a user by email: ${email} - ${tableName}`
  )

  const params = {
    TableName: tableName,
    IndexName: 'emailIndex',
    KeyConditionExpression: 'email = :email',
    ExpressionAttributeValues: {
      ':email': {
        S: email,
      },
    },
  }

  try {
    const result = await ddbDocClient.send(new QueryCommand(params))
    if (!result.Items) {
      return [{} as User, statusCodes.NOT_FOUND, 'user not found']
    }

    return [unmarshall(result.Items[0]) as User, statusCodes.OK, '']
  } catch (error) {
    return [
      {} as User,
      error.$metadata.httpStatusCode,
      (error as Error).message,
    ]
  }
}

Comments