AWS Lambda(Node.js)からAWS AppSync(GraphQL)のAPIを利用してみた


My Redmine

吉岡です。最近寒くなってきましたね。 鍋と熱燗とコタツの季節が来たと思うと、少しテンションが上がります!

さて、今回はAWS Amplifyを利用して開発を行った際にAppSync(GraphQL)について得た知見について書きたいと思います。

背景

AWS Amplifyを利用してウェブアプリケーションを作りました。そして、バックエンド側でAWS AppSyncを利用して入力されたデータに対して、定期的にLambda(Node.js)を実行して、不要になったデータの削除する処理を行う処理を実装しました。


簡略図

ちなみに、AWS Amplify と AWS AppSyncはAWSが提供しているマネージドサービスで、フロントエンドがデプロイできたり、GraphQLをお手軽に利用できるサービスになります。

参考:AWS Amplify
https://aws.amazon.com/jp/amplify/

参考:AWS AppSync
https://aws.amazon.com/jp/appsync/

問題発生

まずは、今回一番のハマりどころであった、APIへアクセスする際の認証について書きたいと思います。

AppSyncにアクセスする時に制限をかける場合はIAMを利用した方法とApiKeyを利用した方法があります。今回はApiKeyを利用したアクセスではなく、IAM(ロール)を利用したアクセスを考えました。(ApiKeyの管理とかしたくない)

  1. まず最初に、Amplifyのドキュメント(Functions - Overview - Amplify Docs)にLambdaからAppSync(GraphQL)へのアクセス方法が書かれていましたので、そちらを参考にささっとコードを書いて実行したのですが、うまく動かず。。

  2. 他に情報はないかと思い、検索すると情報はそこそこ出てきました(技術系ブログがよく引っかかりました)。ですが、その多くはApiKeyを利用したアクセス方法の解説でした。IAM(ロール)を利用したアクセス方法はなかなかこれと言った情報が見つかりませんでした。

  3. 仕方なくAWSのドキュメントに戻り、「認証」というキーワードを頼りにあちこち調べたら、認証モードが IAM である場合には、 IAM クレデンシャルを使用した署名をリクエストに付与する必要がということで、何やら署名を取得しないといけないようです。
    AWS API リクエストの署名 - AWS 全般のリファレンス

  4. 上記ドキュメントを読みながら、さらに調べましたところ、なんと!参考サイト(上記Amplifyのドキュメント)のやり方ではなく、AppSyncのドキュメント(NodeJS クライアントアプリを作成する - AWS AppSync)の方を参考にすると解決できました!!

AppSyncのドキュメントを見るのはそりゃそうか!最初っからAppSyncで探せば良かった!!と思いつつも、Amplifyのドキュメントのサンプルで動かなかったのは謎です。。(cognitoの絡みかしら?と思いつつ、そっとブラウザのタブを閉じました。)

コード

実際のコードは以下のような感じです。

const aws = require('aws-sdk')
const AWSAppSyncClient = require('aws-appsync').default
const gql = require('graphql-tag')

const listTempUserDatas = gql`
  query ListUserDatas(
    $filter: ModelUserDataFilterInput
    $limit: Int
    $nextToken: String
  ) {
    listUserDatas(filter: $filter, limit: $limit, nextToken: $nextToken) {
      items {
        id
        email
        name
        timestamp
      }
      nextToken
    }
  }
`

const url = process.env.API_TEMPDATAAPI_GRAPHQLAPIENDPOINTOUTPUT
const region = process.env.REGION
const client = new AWSAppSyncClient({
  url: url,
  region: region,
  auth: {
    type: 'AWS_IAM',
    credentials: ()=> aws.config.credentials
  },
  disableOffline: true
})

exports.handler = async (event) => {

  console.log('Reference Time:', new Date(referenceTime))

  try {
    const response = await client.query({ query: listTempUserDatas })
    const items = response.data.listTempUserDatas.items
    console.log('items: ',items)

    return {
      statusCode: 200,
      body: items,
      headers: {
        "Access-Control-Allow-Origin": "*",
      }
    }
  } catch (err) {
    console.log('error posting to appsync: ', err)
  }
}

その他の問題

その他、いくつかハマったところがありましたので、紹介したいと思います。

1. LambdaのLayerについて

const AWSAppSyncClient = require('aws-appsync').default

aws-appsyncをrequireしてるのですが、これを通常のnpm installを利用すると Lambda 関数 xxxx のデプロイパッケージが大きすぎて、インラインコード編集を有効にできません。 というメッセージが表示されてインライン編集ができなくなってしまいます。 別途aws-appsyncがrequireされたLayerを準備して、使用するLambdaに設定(追加)する必要がありました。

Layerについては以下のドキュメントをご確認ください。
AWS Lambda レイヤー - AWS Lambda

2. Node.jsの非同期処理について

そもそもNode.jsをよく理解していなかった話ですが、LambdaでNode.jsを利用して通信する場合は非同期処理(async, await)の利用は必須でした。
Node.js の AWS Lambda 関数ハンドラー - AWS Lambda

最初よく分かってなくて、なかなか思ったようなレスポンスが得られなくて苦労しました。

3. ドキュメントの話

Amplifyを利用しているからと行ってAmplifyのドキュメントばかり調べるのではなく、Amplifyが利用しているサービスのドキュメントも調べる。(今回はAppSyncのドキュメントも見るべきでした)

まとめ

以上、無事にLambdaからAppSyncにアクセスできるようになり、無事にスケジューリングされた処理を実行できるようになりました!個人的には学習コストは高めだと思いますが、覚えてしまえば非常に便利で開発速度が上がりそうです。

今後も、積極的にAWS Amplifyを利用していきたいと思います!!


My Redmine

こちらの記事もオススメです!
AWS Amplify のログイン認証機能を試してみた
「AWS Amplify」を利用して、ログイン画面の実装について手順を紹介します。
お客様のご指摘から「My Redmine」を改善できました
お客様のご協力により、サービスを改善できたことはとてもうれしいです。
ラズパイを使って室温と外気温の関係を視覚的に調査
想像していた以上に簡単に室温管理・分析のための仕組みを構築することができました。
フレックスタイム制の会社側視点でのメリット
フレックスタイム制の導入で従業員の満足度向上・労務管理の簡素化などが実現できました。
マインドマップを使ってAWSクラウドプラクティショナー試験の勉強をしています
マインドマップ作成ツール「XMind」を使用。マインドマップを用いることで頭の中が整理されより理解を深めることができます。
ファーエンドテクノロジーからのお知らせ(2024/05/09更新)
2024年5月11日 オライリー本の全冊公開日のお知らせ(もくもく勉強会も同時開催)
ファーエンドテクノロジーが所蔵するオライリー本(全冊)公開日のご案内です。公開日には「もくもく勉強会」も同時開催します。
入門Redmine 第6版 出版記念企画セミナー「Redmineのアクセス制御」【2024/5/30開催】
入門Redmine 第6版(2024年3月23日発売)の書籍から「Redmineのアクセス制御」について解説します。
My Redmine 初回ご契約で「入門Redmine 第6版」プレゼントのお知らせ
Redmineのクラウドサービス「My Redmine」を初めてご契約いただいたお客様にRedmine解説書「入門Redmine 第6版」を進呈いたします。
2024年度ブランドパートナーに島根県在住のモデル ユイさんを継続起用
ユイさん(モデルスタジオミューズ所属)をファーエンドテクノロジーの2024年度ブランドパートナーとして継続して起用します。
Redmineの最新情報をメールでお知らせする「Redmine News」配信中
新バージョンやセキュリティ修正のリリース情報、そのほか最新情報を迅速にお届け