Lambda 函数 GraphQL 解析器

2025-06-04

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}")
}


Enter fullscreen mode Exit fullscreen mode

在本教程中,我将教您如何创建使用两种类型的 Lambda 解析器的应用程序:

  1. Lambda 解析器与另一个 API 对话并通过查询返回 GraphQL 响应

  2. 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.


Enter fullscreen mode Exit fullscreen mode

如果您尚未安装和配置 Amplify CLI,请按照此处的说明进行操作。

接下来,安装 AWS Amplify 库:



npm install aws-amplify


Enter fullscreen mode Exit fullscreen mode

创建 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


Enter fullscreen mode Exit fullscreen mode

使用以下代码更新该函数:



// 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))
}


Enter fullscreen mode Exit fullscreen mode

在上面的函数中,我们使用了axios库来调用另一个 API。为了使用 axios,我们需要在函数文件夹中安装它。我们还会安装它uuid以供稍后使用:



cd amplify/backend/function/currencyfunction/src

npm install axios uuid

cd ../../../../../


Enter fullscreen mode Exit fullscreen mode

现在函数已经创建完成,我们需要创建 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


Enter fullscreen mode Exit fullscreen mode

接下来,在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}")
}


Enter fullscreen mode Exit fullscreen mode

现在 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


Enter fullscreen mode Exit fullscreen mode

现在,资源已部署完毕,您可以尝试查询了!您可以在 AWS AppSync 控制台中测试查询。要打开 API 仪表板,请在终端中运行以下命令:



amplify console api

? Please select from one of the below mentioned services: GraphQL


Enter fullscreen mode Exit fullscreen mode

在查询编辑器中,运行以下查询:



# 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
  }
}


Enter fullscreen mode Exit fullscreen mode

此查询应返回加密货币信息数组。

更新 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


Enter fullscreen mode Exit fullscreen mode

接下来,让我们更新函数以使用新的数据库。



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:
  ◉ createread
  ◉ 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


Enter fullscreen mode Exit fullscreen mode

接下来,我们将更新 lambda 函数。目前,该函数代码仅位于一个文件index.js中,该文件位于amplify/backend/function/currencyfunction/src/index.js。在src文件夹中,创建两个新文件:createCoin.jsgetCoins.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)
  }
}


Enter fullscreen mode Exit fullscreen mode

在函数的参数中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


Enter fullscreen mode Exit fullscreen mode

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


Enter fullscreen mode Exit fullscreen mode

在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}")
}


Enter fullscreen mode Exit fullscreen mode

现在,部署更改:



amplify push


Enter fullscreen mode Exit fullscreen mode

测试一下

现在,资源已部署完毕,您可以尝试查询了!您可以在 AWS AppSync 控制台中测试查询。要打开您的项目,请在终端中运行以下命令:



amplify console api

? Please select from one of the below mentioned services: GraphQL


Enter fullscreen mode Exit fullscreen mode

测试以下查询:



query listCoins {
  getCoins {
    price_usd
    name
    id
    symbol
  }
}

mutation createCoin {
  createCoin(
    name: "Monero"
    price_usd: "86.85"
    symbol: "XMR"
  ) {
    name price_usd symbol
  }
}


Enter fullscreen mode Exit fullscreen mode

在客户端上测试

如果您想在 React 应用程序中测试它,您可以使用APIAmplify 中的类别:



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))



Enter fullscreen mode Exit fullscreen mode

要查看该项目的最终源代码,请单击此处

文章来源:https://dev.to/dabit3/lambda-function-graphql-resolvers-11cd
PREV
使用 GitHub Actions 在 AWS 上进行 Next.js CI/CD
NEXT
推出“盒装会议应用程序”