GraphQL教程六:AWS AppSync和GraphQL


前面介绍的GraphQL都是在自己的服务器上运行的。下面介绍一下如何在AWS AppSync中使用GraphQL,并分别以DynamoDB及Lambda作为数据源。

GraphQL系列教程:

AWS AppSync介绍

先来看看官网这个架构图:

AWS AppSync
Source:AWS AppSync

AppSync的作用就是为应用程序提供一个统一的接口,可以进行各种查询和操作。它可以用来连接SQL, NoSQL, OpenSearch, HTTP/REST, Lambda等不同的数据源。和自己搭建的服务器相比,在AppSync中可以方便的使用其他AWS服务,比如Cognito,IAM,API Key等等。

在AppSync中又两个重要的概念:

  • Data Source数据源: 数据源可以是持久层的数据存储(SQL / NoSQL),也可以是其他的Lambda函数,或者HTTP API。
  • Resolver:这点和普通GraphQL中的resolver一样,用于定义获取/操作数据的逻辑。

同时需要注意的是,在AppSync中有一个比较重要的概念:Subscription(订阅)。也就是说,当进行数据操作的时候,可以自动触发一切其他的行为,比如Lambda。其最终的定义类似于这样:

AWS AppSync

创建AppSync API(DynamoDB版)

在控制台中创建API

进入AWS AppSync控制台,选择:

  • Create API
  • Build from scratch, 单击”Start”
  • 输入App的名字,比如“AWS AppSync tutorial”后单击“Create”

定义Schema,Resolvers

单击“Edit Schema”之后单击“Create Resources”。这里还以前面用到的StudentType为例。需要注意的是,和前面定义的Schema不同,这里用的类型:

type Student {
	id: ID!
	name: String!
	address: String!
}

其余的都选择默认设置:

AppSync

然后单击”Create”就会创建这个Schema以及配套的DynamoDB table。创建完毕后会返回Schema页面,可以看到queries和mutations都已经创建好了:

AppSync

同时还有配套的Resolvers:

AppSync

单击一个resolver,比如createStudent:

{
  "version": "2017-02-28",
  "operation": "PutItem",
  "key": {
    "id": $util.dynamodb.toDynamoDBJson($util.autoId()),
  },
  "attributeValues": $util.dynamodb.toMapValuesJson($ctx.args.input),
  "condition": {
    "expression": "attribute_not_exists(#id)",
    "expressionNames": {
      "#id": "id",
    },
  },
}

可以看到它首先检测id是否存在:

"expression": "attribute_not_exists(#id)"

然后才进行插入操作:

"operation": "PutItem",
"key": {
  "id": $util.dynamodb.toDynamoDBJson($util.autoId()),
},
"attributeValues": $util.dynamodb.toMapValuesJson($ctx.args.input),

而Response mapping则定义了返回用户的数据格式,这里默认值代表使用DyanomoDB的返回值,意味着新建的Student:

$util.toJson($context.result)

测试Query API

单击屏幕左边的Queries,然后输入以下的Query:

mutation newStudent{
  createStudent(input: {name:"Jack", address:"101 Fake Street"}) {
    id
    name
    address
  }
}

可以看到其返回值为:

{
  "data": {
    "createStudent": {
      "id": "a5bcc986-4539-4331-9723-6065d883f0ee",
      "name": "Jack",
      "address": "101 Fake Street"
    }
  }
}

这个操作也可以再左边的小窗口中操作:

AppSync

再进行一下查询,这个操作完全类似于GraphQL Web UI:

AWS AppSync

创建AppSync API(Lambda版)

创建一个Lambda

为了简单,这里直接在AWS Console中创建一个Lambda:

exports.handler = async (event) => {
    let students = [
        { id: '1', name: 'Lucas', address: '1 Fake Street'},
        { id: '2', name: 'Paul', address: '2 Fake Street'},
        { id: '3', name: 'Jess', address: '3 Fake Street'},
        { id: '4', name: 'Tom', address: '4 Fake Street'},
        { id: '5', name: 'Ned', address: '5 Fake Street'},
        { id: '6', name: 'Dan', address: '6 Fake Street'},
        { id: '7', name: 'Luke', address: '7 Fake Street'},
        { id: '8', name: 'Lucy', address: '8 Fake Street'},
        { id: '9', name: 'Chole', address: '9 Fake Street'},
        { id: '10', name: 'Amy', address: '10 Fake Street'}
    ]
    switch(event.field) {
        case 'getStudent':
            let {id} = event.arguments;
            return students.filter(s => s.id === id)[0]
        default:
            return "Student not found."
    }
};

在AppSync中创建数据源

回到刚才的AppSync API,然后注册一个新的data source:

AWS AppSync

首先删除getStudent resolver到StudentTable的绑定:

AWS AppSync

Request mapping template:

{
  "version" : "2017-02-28",
  "operation": "Invoke",
  "payload": {
        "field": "getStudent",
        "arguments":  $utils.toJson($context.arguments)
  }
}

Response mapping template (系统默认值):

$util.toJson($context.result)

AWS AppSync

测试

下面进行查询,可以看到,getStudent的数据源已经是Lambda,而不是DynamoDB了:

AWS AppSync


文章作者: 逻思
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 逻思 !
  目录