Lambda 函数 GraphQL 解析器
Amplify CLI最近添加了对直接从 Amplify 环境为 AppSync API 部署 Lambda GraphQL 解析器的支持。Lambda 函数解析器允许您使用 JavaScript 编写 AppSync 解析器逻辑。
使用该@function
指令,您可以指定与 GraphQL 架构中的 Lambda 函数交互的操作:
type Mutation {
addEntry(id: Int, email: String): String @function(name: "addEntry-${env}")
}
在本教程中,我将教您如何创建使用两种类型的 Lambda 解析器的应用程序:
-
Lambda 解析器与另一个 API 对话并通过查询返回 GraphQL 响应
-
Lambda 解析器发送查询和变异以与真实的 NoSQL 数据库交互来对其执行创建和读取操作。
在本教程结束时,您应该了解如何使用 Amplify Framework 部署与 Lambda GraphQL 解析器交互的 AppSync GraphQL API。
要查看该项目的最终源代码,请单击此处。
入门
首先,您需要创建一个新的 React 应用程序并在其中初始化一个新的 Amplify 项目:
npx create-react-app gql-lambda
cd gql-lambda
amplify init
# Follow the steps to give the project a name, environment name, and set the default text editor.
# Accept defaults for everything else and choose your AWS Profile.
如果您尚未安装和配置 Amplify CLI,请按照此处的说明进行操作。
接下来,安装 AWS Amplify 库:
npm install aws-amplify
创建 API
我们将创建的第一个 GraphQL API 将从另一个 REST API 查询数据并返回 GraphQL 响应。您将与之交互的 API 是Coinlore API。
让我们首先创建函数:
amplify add function
? Provide a friendly name for your resource to be used as a label for this category in the project: currencyfunction
? Provide the AWS Lambda function name: currencyfunction
? Choose the function runtime that you want to use: NodeJS
? Choose the function template that you want to use: Hello world
? Do you want to access other resources created in this project from your Lambda function? N
? Do you want to invoke this function on a recurring schedule? N
? Do you want to edit the local lambda function now? Y
使用以下代码更新该函数:
// amplify/backend/function/currencyfunction/src/index.js
const axios = require('axios')
exports.handler = function (event, _, callback) {
let apiUrl = `https://api.coinlore.com/api/tickers/?start=1&limit=10`
if (event.arguments) {
const { start = 0, limit = 10 } = event.arguments
apiUrl = `https://api.coinlore.com/api/tickers/?start=${start}&limit=${limit}`
}
axios.get(apiUrl)
.then(response => callback(null, response.data.data))
.catch(err => callback(err))
}
在上面的函数中,我们使用了axios库来调用另一个 API。为了使用 axios,我们需要在函数文件夹中安装它。我们还会安装它uuid
以供稍后使用:
cd amplify/backend/function/currencyfunction/src
npm install axios uuid
cd ../../../../../
现在函数已经创建完成,我们需要创建 GraphQL API。为此,请运行 Amplifyadd
命令:
amplify add api
? Please select from one of the below mentioned services: GraphQL
? Provide API name: currencyapi
? Choose an authorization type for the API: API key
? Enter a description for the API key: public
? After how many days from now the API key should expire (1-365): 365 (or your preferred expiration)
? Do you want to configure advanced settings for the GraphQL API: N
? Do you have an annotated GraphQL schema? N
? Do you want a guided schema creation? Y
? What best describes your project: Single object with fields
? Do you want to edit the schema now? Y
接下来,在amplify/backend/api/currencyapi/schema.graphql中,使用以下内容更新架构:
type Coin {
id: String!
name: String!
symbol: String!
price_usd: String!
}
type Query {
getCoins(limit: Int start: Int): [Coin] @function(name: "currencyfunction-${env}")
}
现在 API 和 Lambda 函数都已创建。要部署并上线,您可以运行以下push
命令:
amplify push
Current Environment: dev
| Category | Resource name | Operation | Provider plugin |
| -------- | ------------- | --------- | ----------------- |
| Api | currencyapi | Create | awscloudformation |
| Function | currencyfunction | Create | awscloudformation |
? Are you sure you want to continue? (Y/n) Y
现在,资源已部署完毕,您可以尝试查询了!您可以在 AWS AppSync 控制台中测试查询。要打开 API 仪表板,请在终端中运行以下命令:
amplify console api
? Please select from one of the below mentioned services: GraphQL
在查询编辑器中,运行以下查询:
# basic request
query listCoins {
getCoins {
price_usd
name
id
symbol
}
}
# request with arguments
query listCoinsWithArgs {
getCoins(limit:3 start: 10) {
price_usd
name
id
symbol
}
}
此查询应返回加密货币信息数组。
更新 API 以针对 NoSQL 数据库执行 CRUD 操作
现在基本 API 已启动并运行,让我们创建一个数据库并更新 API 以对其执行创建和读取操作。
首先,我们将创建数据库:
amplify add storage
? Please select from one of the below mentioned services: NoSQL Database
? Please provide a friendly name for your resource that will be used to label this category in the project: currencytable
? Please provide table name: currencytable
? What would you like to name this column: id
? Please choose the data type: string
? Would you like to add another column? Y
? What would you like to name this column: name
? Please choose the data type: string
? Would you like to add another column? Y
? What would you like to name this column: symbol
? Please choose the data type: string
? Would you like to add another column? Y
? What would you like to name this column: price_usd
? Please choose the data type: string
? Would you like to add another column? N
? Please choose partition key for the table: id
? Do you want to add a sort key to your table? N
? Do you want to add global secondary indexes to your table? N
? Do you want to add a Lambda Trigger for your Table? N
接下来,让我们更新函数以使用新的数据库。
amplify update function
? Please select the Lambda Function you would want to update: currencyfunction
? Do you want to update permissions granted to this Lambda function to perform on other resources in your project? Y
? Select the category: storage
? Select the operations you want to permit for currencytable:
◉ create
◉ read
◉ update
❯◉ delete
? Do you want to invoke this function on a recurring schedule? N
? Do you want to edit the local lambda function now? Y
接下来,我们将更新 lambda 函数。目前,该函数代码仅位于一个文件index.js中,该文件位于amplify/backend/function/currencyfunction/src/index.js。在src文件夹中,创建两个新文件:createCoin.js和getCoins.js。在接下来的步骤中,我们将更新index.js,并在另外两个新文件中填充代码。
index.js
const getCoins = require('./getCoins')
const createCoin = require('./createCoin')
exports.handler = function (event, _, callback) {
if (event.typeName === 'Mutation') {
createCoin(event, callback)
}
if (event.typeName === 'Query') {
getCoins(callback)
}
}
在函数的参数中event
,有一个typeName
字段会告诉我们该操作是 Mutation 还是 Query。如果有多个 Queries 或 Mutation,还有一个fieldName
参数会告诉你实际执行的字段。
我们将使用该字段根据操作类型typeName
来调用createCoin
或。getCoins
getCoins.js
const AWS = require('aws-sdk')
const region = process.env.REGION
const storageCurrencytableName = process.env.STORAGE_CURRENCYTABLE_NAME
const docClient = new AWS.DynamoDB.DocumentClient({region})
const params = {
TableName: storageCurrencytableName
}
function getCoins(callback) {
docClient.scan(params, function(err, data) {
if (err) {
callback(err)
} else {
callback(null, data.Items)
}
});
}
module.exports = getCoins
在getCoins中,我们调用 DynamoDBscan
操作来读取数据库并返回数组中的所有值。我们还使用DynamoDB.DocumentClient sdk 来简化使用 JavaScript 处理 Amazon DynamoDB 中项目的操作。
createCoin.js
const AWS = require('aws-sdk')
const { v4: uuid } = require('uuid')
const region = process.env.REGION
const ddb_table_name = process.env.STORAGE_CURRENCYTABLE_NAME
const docClient = new AWS.DynamoDB.DocumentClient({region})
function write(params, event, callback){
docClient.put(params, function(err, data) {
if (err) {
callback(err)
} else {
callback(null, event.arguments)
}
})
}
function createCoin(event, callback) {
const args = { ...event.arguments, id: uuid() }
var params = {
TableName: ddb_table_name,
Item: args
};
if (Object.keys(event.arguments).length > 0) {
write(params, event, callback)
}
}
module.exports = createCoin
在createCoin 函数中,我们通过传入的参数对 DynamoDB 表进行操作。我们还会在服务器上自动生成 ID,并使用uuidputItem
库为项目填充唯一的 ID 。
最后,我们将更新amplify/backend/api/currencyapi/schema.graphql中的 GraphQL Schema以添加突变定义:
# amplify/backend/api/currencyapi/schema.graphql
type Coin {
id: String!
name: String!
symbol: String!
price_usd: String!
}
type Query {
getCoins(limit: Int start: Int): [Coin] @function(name: "currencyfunction-${env}")
}
# new mutation definition
type Mutation {
createCoin(name: String! symbol: String! price_usd: String!): Coin @function(name: "currencyfunction-${env}")
}
现在,部署更改:
amplify push
测试一下
现在,资源已部署完毕,您可以尝试查询了!您可以在 AWS AppSync 控制台中测试查询。要打开您的项目,请在终端中运行以下命令:
amplify console api
? Please select from one of the below mentioned services: GraphQL
测试以下查询:
query listCoins {
getCoins {
price_usd
name
id
symbol
}
}
mutation createCoin {
createCoin(
name: "Monero"
price_usd: "86.85"
symbol: "XMR"
) {
name price_usd symbol
}
}
在客户端上测试
如果您想在 React 应用程序中测试它,您可以使用API
Amplify 中的类别:
import { API, graphqlOperation } from 'aws-amplify'
import { getCoins } from './graphql/queries'
import { createCoin } from './graphql/mutations'
// mutation
const coin = { name: "Bitcoin", symbol: "BTC", price: "10000" }
API.graphql(graphqlOperation(createCoin, coin))
.then(data => console.log({ data }))
.catch(err => console.log('error: ', err))
// query
API.graphql(graphqlOperation(getCoins))
.then(data => console.log({ data }))
.catch(err => console.log('error: ', err))
文章来源:https://dev.to/dabit3/lambda-function-graphql-resolvers-11cd要查看该项目的最终源代码,请单击此处。