为 DynamoDB JavaScript 解析器推出新的 亚马逊云科技 AppSync 模块和函数

本文由高级解决方案架构师 Kim Wendt 撰写

亚马逊云科技 AppSync 是一项允许您在云中构建、管理和托管 GraphQL API 的服务。使用 AppSync,您只需编写 GraphQL 架构并使用解析器连接到数据源即可。解析器是 AppSync 转换 GraphQL 请求以从不同数据源检索信息的方式。2022 年 11 月,AppSync 推出了 JavaScript 解析器 , 让开发者可以更轻松地编写 AppSync 业务逻辑。JavaScript 解析器的推出包括用于简化开发的 NPM 库: @aws-appsync/utils 用于在代码编辑器中提供类型验证和自动完成功能, @aws-appsync/esl int-p lugin 用于在开发过程中快速发现 和修复问题。

今天,我们推出了与 DynamoD B 数据源交互的新模块和函数,使为 Amazon DynamoDB 编写解析器变得更加容易。新模块简化了为常见操作(如传 、 获取 删除 更新 扫描 同步 和 查询)创建 DynamoDB 请求所需的代码。 此外,该实用程序还提供操作助手,帮助您在更新期间对项目属性进行细致的更改。该模块在公共 @aws-appsync/utils 包中提供,还有类型定义,允许开发人员在使用 TypeScript 时在本地编写类型安全的代码。

概述

适用于 DynamoDB 数据源的新 JavaScript 模块使只需几行代码即可轻松表达 DynamoDB 请求。例如,假设我们想要向我们的 DynamoDB 表中添加一个新项目,其 主键 id, 并有一组属性的键/值对。下面的代码使用 ddb. put 实用程序,该 实用程序使用密钥和物品作为输入来构造 Dynamo DB PutRequest。

import * as ddb from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
    const item = { id: util.autoId(), ...ctx.args };
    return ddb.put({ key: { id: item.id }, item });
}

export const response = (ctx) => ctx.result;

我们还可以使用扫描操作从我们的 DyanaMoDB 数据源检索信息。 例如,假设我们在表格中添加了更多项目,现在我们想要检索这些项目的列表。下面的代码使用 ddb.scan 实用程序,该实用程序使用输入 限制 nextToken 值对从 DynamoDB 返回的结果进行分页。

import * as ddb from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
    const { limit = 10, nextToken } = ctx.args;
    return ddb.scan({ limit, nextToken });
}

export const response = (ctx) => ctx.result.items;

现在轮到你将这些函数与带有其他解析器逻辑的 AppSync API 一起使用。

入门

你可以在 AppSync 控制台中开始使用适用于 DynamoDB 的 JavaScript 模块。

  1. 在 AppSync 控制台中,选择 创建 API
  2. 对于 API 类型 ,选择所有默认值,然后选择 下一步
  3. 指定 API 详细信息 页面上,将您的 API 命名为 Todo-API ,然后选择 下一步。
  4. 指定 GraphQL 资源 页面上,选择立即 创建由 DynamoDB 表支持的类型

AppSync 控制台可以帮助您创建新的 GraphQL 类型、与该类型相关的操作以及用作数据源的 DynamoDB 表。为了说明新的 JavaScript 模块函数,我们将创建一个包含以下字段的 Todo 类型: ID 所有者 名称 严重性 Du eOn。

  1. 使用以下值填写模型信息。要添加字段,请选择 添加新字段 。在型号名称中,输入 ToDo 。在 “其他设置” 部分中,将解析器运行时保留为 AppSync JavaScript。
  1. preview of the create API wizard在配置模型表部分中,使用以下值填写表名、主键和排序键,然后选择 下一步

Create DynamoDB table

  1. 确认您的 API 详细信息,然后选择 创建 API

Tod o-API 、DynamoDB 数据源和 JavaScript 解析器是自动为你创建的。在 架构 页面中,您可以查看和修改 GraphQL 架构、编辑解析器或将新的解析器附加到架构中的字段。让我们更新解析器逻辑,使用适用于 DynamoDB 的新 JavaScript 模块。

  1. 导航到 “架” 页面。在 解析器 部分,在 过滤器类型 中输入 突变... 搜索栏。
  2. create Todo (...): ToDo 字段选择 todoT able 解析器。

createToDo 解析器包含一个辅助函数,用于构造 DynamoDB PutItem 请求,包括条件、键和属性值。 这些值全部转换为地图对象,这就是 DynamoDB 对 Put Item 请求的期望。

function dynamodbPutRequest(params) {
    const { key, values, condition: inCondObj } = params;
    
    let condition;
    if (inCondObj) {
        condition = JSON.parse(util.transform.toDynamoDBConditionExpression(inCondObj));
        if (condition && condition.expressionValues && !Object.keys(condition.expressionValues).length) {
            delete condition.expressionValues;
        }
    }
    return {
        operation: 'PutItem',
        key: util.dynamodb.toMapValues(key),
        attributeValues: util.dynamodb.toMapValues(values),
        condition,
    }
}

让我们使用 DynamoDB 的 JavaScript 模块来简化这个逻辑。

  1. 将以下 import 语句添加到解析器代码中。
import { put } from '@aws-appsync/utils/dynamodb';
  1. 使用以下代码替换请求处理程序(并可选择删除 DynamodbputRequest 函数),然后选择 “保存”。
export function request(ctx) {
    const { id, owner, ...item } = ctx.args.input;
    const key = { id, owner };
    
    const condition = { };
    Object.keys(key).forEach(k => condition[k] = { attributeExists: false });
    
    return put({key, item, condition});
}

使用新的模块函数,我们能够简化构造条件运算、键和属性值的逻辑。现在你不再需要使用 t omap Values 或 toDynamodbConditionExpression 实用程序;这个功能在 put 实用程序方法中抽象出来了。

让我们来看一下用于 update ToDo 操作的更复杂的解析器。

  1. 导航到 “架” 页面。在 解析器 部分,在 过滤器类型 中输入 突变... 搜索栏。
  2. update Todo (...): ToDo 字段选择 TodoT able 解析器。

createToDo 解析器类似,updateToDo 解析器包含一个用于构造 DynamoDB Update Item 请求的辅助函数。 让我们使用新模块简化这个逻辑。

  1. 将以下 import 语句添加到解析器代码中。
import { update, operations as ops } from '@aws-appsync/utils/dynamodb';
  1. 用下面的代码替换请求处理程序,然后选择 Save
export function request(ctx) {
    const { id, owner, ...values } = ctx.args.input;
    const key = { id, owner };
    
    const condition = {};
    Object.keys(key).forEach(k => condition[k] = { attributeExists: true });
    
    const updateObj = {};
    Object.entries(values).forEach(([k,v]) => updateObj[k] = v ?? ops.remove());
    
    return update({ key, condition, update: updateObj });
}

使用适用于 DynamoDB 的 JavaScript 模块,我们可以利用 操作 和 更新函数来简化用于创建更新表达式的代码。 在这里,要在更新期间删除某个属性,我们会检查指定的属性是否为空,然后使用 operat ions.remove () 将其标记为已删除。

操作助手提供的函数可用于在更新期间对物品属性采取不同的操作。可用的助手有:

  • add () :添加新属性,包括具有嵌套属性的复杂结构
  • re@@ move () :从物品中移除一个属性
  • replace () :在更新期间替换现有属性(或嵌套属性)
  • inc@@ rement () :按给定数字递增属性
  • decrement () :将属性减去给定数字
  • append () :将项目添加到属性列表的末尾
  • prepend () :将项目添加到属性列表的开头
  • updateListItem () :更新列表中特定索引处的项目

使用操作助手,你可以在 JavaScript 解析器中用几行代码编写复杂的更新操作。例如:

import { update, operations as ops } from '@aws-appsync/utils/dynamodb';
export function request(ctx) {
    const updateObj = {
        count: ops.increment(1),
        friends: ops.append(['John']),
        address: ops.add({ street1: '123 Main St', street2: 'Unit A', city: 'New York', zip: '10001' }),
        pets: [ops.updateListItem('rex', 2)],
    };
    const condition = { friends: { size: { lt: 5 } }, id: { attributeExists: true } };
    return update({ key: { id: 1 }, update: updateObj, condition });
}

以下更新请求将:

  • 增加计数属性
  • 将 “John” 作为好友添加到好友列表中
  • 向商品添加地址
  • 并更改 pet 属性的第 3 个列表条目的值。

仅当存在具有所提供密钥 ( id ) 的物品且好友列表的大小小于 5 时,才允许更新。

您可以在 AppSync 文档 中找到有关模块功能的更多信息。有关如何使用这些新功能的示例,请参阅 亚马逊云科技 AppSync 示例 存储库。

结论

在这篇文章中,我们回顾了 DynamoDB 的新 JavaScript 模块,该模块旨在简化 AppSync 解析器中的解析器逻辑。此外,我们还介绍了如何轻松开始使用 亚马逊云科技 AppSync 以及如何编写解析器以使用新模块。 要了解有关 JavaScript 解析器和 DynamoDB 新函数的更多信息,请参阅 文档 和教程。 您还可以在样本 库中找到易于使用的 示例 和指南 。