📊

AWS AppSyncでLambdaをDataSoruceとした場合のLambda関数の入出力

2021/08/17に公開

GraphQL入門としてAppSyncを触ってみました。

AppSyncのデータソースとしてLambdaを選択した場合、

  • Lambda関数へ入力値はどんなふうに渡るのか
  • どのような値を返せば良いのか

についてイメージしづらかったため、実際に試してみました。

環境

  • (端末の)node 15.11.0
  • aws-cdk 1.117.0
  • typescript 4.3.5
  • @types/aws-lambda 8.10.81

schema.graphql

type user {
  id: String!
  name: String!
}
type Query {
  userFind(id: String!): user!
}

このようなシンプルなschema.graphqlを用意します。

LambdaHandler

// index.ts
import { AppSyncResolverEvent } from 'aws-lambda'

export const userFindHandler = async (
  event: AppSyncResolverEvent<
    {
      id: string
    },
    unknown
  >
) => {
  console.log(JSON.stringify({ event }))

  return {
    id: 'USER_ID',
    name: 'USER_NAME'
  }
}

データソースとなるLambda関数です。eventの内容については後述しますが、@types/aws-lambdaのAppSyncResolverEventを利用することで楽に型付けができます。

やっていることはただ入力値であるeventを出力して固定値を返しているだけです。実際はここでDBなりにアクセスしてデータを取ってきて返すことになります。

CDK

IaCはCDKを選択します。リソースの作成内容はソース内コメントで補足しています。

import * as cdk from '@aws-cdk/core'
import * as appsync from '@aws-cdk/aws-appsync'
import * as lambda from '@aws-cdk/aws-lambda'

export class CdkStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props)

    // AppSyncAPIを作成
    const api = new appsync.GraphqlApi(this, 'my-appsync-api', {
      name: 'my-appsync-api',
      schema: appsync.Schema.fromAsset('../schema.graphql'),
      authorizationConfig: {
        defaultAuthorization: {
          authorizationType: appsync.AuthorizationType.API_KEY,
        },
      },
      xrayEnabled: true,
    })

    // Lambda関数を作成
    const userFindFn = new lambda.Function(this, 'user-find-fn', {
      runtime: lambda.Runtime.NODEJS_14_X,
      code: lambda.Code.fromAsset('../server/dist'),
      handler: 'index.userFindHandler',
    })

    // Lambda関数をDataSourceとしてAppSyncAPIと紐付ける
    const userFindDS = api.addLambdaDataSource('userFindDataSource', userFindFn)

    // schema.graphqlで定義した中のどの操作とマッピングするかを指定
    userFindDS.createResolver({
      typeName: 'Query',
      fieldName: 'userFind',
    })
  }
}

AWS WebコンソールからuserFindクエリを呼び出す

userFindクエリに id: "1" を渡して実行しました。

出力

返り値は

{
  "data": {
    "userFind": {
      "id": "USER_ID",
      "name": "USER_NAME"
    }
  }
}

のように来るようです。

Lambdaへの入力値

console.log(JSON.stringify({ event }))

こちらの出力は以下です。実際にはrequestオブジェクトなどもありますが、クエリのパラメータであるarguments以外は省略している点に留意してください。

{
    "event": {
        "arguments": {
            "id": "1"
        },
    }
}

つまり、例えば

const { id } = event.arguments

のように渡されたidを取得して利用できそうですね。

参考

Discussion