メインコンテンツに移動
デベロッパーのためのクラウド活用方法

AWS Lambda Powertools Python入門 ~ 第 6  回 EventHandler Utility - GraphQL 編

2022-11-02 | Author : 福井 厚

はじめに

皆さん、こんにちは。AWSソリューションアーキテクトの福井です。本連載は、AWS Lambda Powertools for Python の提供する様々なユーティリティーについて、その利用方法を紹介するシリーズです。

さて、第 5 回 では、AWS Lambda Powertools for Python の EventHandler ユーティリティーの REST API の使い方についてご紹介しました。今回は Event Handler の GraphQL API についてご紹介します。なお本記事は、AWS Lambda Powertools Python 1.29.2 を対象としています。


X ポスト » | Facebook シェア » | はてブ »

builders.flash メールメンバー登録

builders.flash メールメンバー登録で、毎月の最新アップデート情報とともに、AWS を無料でお試しいただけるクレジットコードを受け取ることができます。

今すぐ登録 »

Event Handler (Core Utilities)

AWS Lambda Powertools for Python の Event Handler は、REST API と GraphQL API の両方が提供されています。前回は、REST API について紹介しましたが、今回は GraphQL API について紹介します。

Event Handler GraphQL API を利用することで GraphQL API のクエリパラメータを自動的に関数の引数に変換してくれます。また関数のレスポインスを自動的に GraphQL フィールドにマップする機能も提供しています。

GraphQL API

AWS AppSync Direct Lambda ResolverAmplify GraphQL Transformer のためのイベントハンドラです。

このユーティリティーの主な特長は以下の通りです。

  • 自動的に API の引数をパースして関数の引数に変換
  • GraphQL のフィールド名に厳密に一致するか、またはフィールドすべてを関数へ渡すかを選択可能
  • リゾルバとアイデンティティー情報へアクセスするための Data classes utilities との統合
  • Python 3.8 以上の非同期関数とジェネレーターをサポート


Direct Lambda Resolverとは : Apache Velocity Template (VTL) をバイパスするためのカスタムの AppSyncリゾルバ と、関数のレスポンスを自動的に GraphQL フィールドにマップする機能を提供

利用方法

AWS Lambda Powertools PythonをLambda関数に組み込む方法については、第 1 回 の記事を参照ください。

このユーティリティーを利用するためには、作成済みの AppSync GraphQL API と、Lambda 関数を実行可能な IAM パーミッションが必要です。それ以外はこのユーティリティーの利用に追加のパーミッションは必要ありません。

Serverless Application Model (SAM) テンプレートを実行

今回は以下の Serverless Application Model (SAM) テンプレートを実行して AppSync API のサンプルを AppSync Direct Lambda Resolver と共に利用します。

python
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: >
  05_eventhandler_graphql_demo

  Sample SAM Template for 05_eventhandler_graphql_demo

Globals:
  Function:
    Timeout: 5
    Tracing: Active
    Environment:
      Variables:
        LOG_LEVEL: INFO
        POWERTOOLS_LOGGER_SAMPLE_RATE: 0.1
        POWERTOOLS_LOGGER_LOG_EVENT: true
        POWERTOOLS_SERVICE_NAME: sample_resolver

Resources:
  # Lambda function
  TodosFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: src/
      Handler: app.lambda_handler
      Runtime: python3.9
      Architectures:
        - x86_64

      # AWS Lambda Powertools for Python
      Layers:
        - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPython:36

  # IAM Permissions and Roles
  AppSyncServiceRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Service:
                - "appsync.amazonaws.com"
            Action:
              - "sts:AssumeRole"

  InvokeLambdaResolverPolicy:
    Type: "AWS::IAM::Policy"
    Properties:
      PolicyName: "DirectAppSyncLambda"
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Action: "lambda:invokeFunction"
            Resource:
              - !GetAtt TodosFunction.Arn
      Roles:
        - !Ref AppSyncServiceRole

  # GraphQL API
  TodosApi:
    Type: "AWS::AppSync::GraphQLApi"
    Properties:
      Name: TodosApi
      AuthenticationType: "API_KEY"
      XrayEnabled: true

  TodosApiKey:
    Type: AWS::AppSync::ApiKey
    Properties:
      ApiId: !GetAtt TodosApi.ApiId

  TodosApiSchema:
    Type: "AWS::AppSync::GraphQLSchema"
    Properties:
      ApiId: !GetAtt TodosApi.ApiId
      Definition: |
        schema {
            query:Query
        }

        type Query {
            getTodo(id: ID!): Todo
            listTodos: [Todo]
        }

        type Todo {
            id: ID!
            title: String
            description: String
            done: Boolean
        }

  # Lambda Direct Data Source and Resolver
  TodosFunctionDataSource:
    Type: "AWS::AppSync::DataSource"
    Properties:
      ApiId: !GetAtt TodosApi.ApiId
      Name: "HelloWorldLambdaDirectResolver"
      Type: "AWS_LAMBDA"
      ServiceRoleArn: !GetAtt AppSyncServiceRole.Arn
      LambdaConfig:
        LambdaFunctionArn: !GetAtt TodosFunction.Arn

  ListTodosResolver:
    Type: "AWS::AppSync::Resolver"
    Properties:
      ApiId: !GetAtt TodosApi.ApiId
      TypeName: "Query"
      FieldName: "listTodos"
      DataSourceName: !GetAtt TodosFunctionDataSource.Name

  GetTodoResolver:
    Type: "AWS::AppSync::Resolver"
    Properties:
      ApiId: !GetAtt TodosApi.ApiId
      TypeName: "Query"
      FieldName: "getTodo"
      DataSourceName: !GetAtt TodosFunctionDataSource.Name

Outputs:
  HelloWorldFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt TodosFunction.Arn

  HelloWorldAPI:
    Value: !GetAtt TodosApi.Arn

GraphQL スキーマ

この SAM テンプレートで実行される GraphQL スキーマは以下の通りです。

python
schema {
    query: Query
}

type Query {
    getTodo(id: ID!): Todo
    listTodos: [Todo]
}

type Todo {
    id: ID!
    userId: String
    title: String
    completed: Boolean
}

Resolver デコレーター

app.resolver() デコレーターを利用して関数を GraphQL タイプとフィールドにマッチさせることができます。

このサンプルでは 2 つの Python の関数を利用して Query タイプ内の getTodolistTodos  の 2 つのフィールドを解決します。スキーマ定義に従ってアウトプットを生成するためにスカラタイプのユーティリティー (この後、スカラ関数についても説明します) を利用しています。このクエリの Lambda Direct Data Source と Resolver として以下の Lambda 関数が実行されます。

Tips : GraphQL 引数は関数のキーワード引数に渡されます。(例 : getTodo(id: “id_value”)get_todo(id=“id_value”) を呼び出します。)

Screenshot of a Python code example demonstrating the use of AWS Lambda Powertools AppSyncResolver for AWS AppSync GraphQL resolver logic. Highlights include setup for logging, tracing, event handling, sample queries, and Lambda context injection.

スカラ関数

AWS AppSync Scalar types と共に実行する場合、データ検証の目的で同じ値を生成したいと思うかもしれません。利便性のため、最も一般的に利用される値を scalar_types_utils モジュールの関数として利用可能にしています。

以下のテーブルに関連するスカラ値を返す関数をリストしています。

スカラ型

スカラ関数

サンプル値

ID

scalar_types_utils.make_id()

e916c84d-48b6-484c-bef3-cee3e4d86ebf

AWSDate

scalar_types_utils.aws_date()

2022-07-08Z

AWSTime

scalar_types_utils.aws_time()

15:11:00.189Z

AWSDateTime

scalar_types_utils.aws_datetime()

2022-07-08T15:11:00.189Z

AWSTimestamp

scalar_types_utils.aws_timestamp()

1657293060

まとめ

いかがでしたでしょうか。今回は、AWS Lambda Powertools Python の EventHandler ユーティリティーの GraphQL API について紹介しました。

Event Handler Utility の Resolver デコレーターを利用することで、簡単に Appsync の GraphQL を AWS Lambda 関数にマップできることがご理解頂けたのではないでしょうか。

今回で AWS Lambda Powertools for Python のコアユーティリティーの紹介は終わりました。次回からはそれ以外のユーティリティーについてご紹介したいと思います。どうかお楽しみに。

筆者プロフィール

福井 厚
アマゾン ウェブ サービス ジャパン合同会社
シニアソリューションアーキテクト
Developerスペシャリスト - DevAx

2015 年からアマゾンウェブサービスジャパンでソリューションアーキテクトとして活動。最近は、Developer スペシャリスト SA として日々開発者の方にクラウドネイティブなモダンアプリケーション開発の技術支援を行なっています。

A portrait photograph of a smiling man wearing glasses, a beard, and a red sweater over a pink shirt. The image is titled 'Portrait of Fukui Atsushi, 2021.'