AWS Workshops攻略記：AppSync Immersion Day(+VTLへの愚痴)

# はじめに
AWSのWorkshop(ハンズオン)がまとまったサイト「AWS Workshops」使ってますか？
今回はAppsyncが４時間ほどで学べる「Appsync Immersion Day」を試してみました。英語に抵抗感ある方向けに、布教がてらのレポを書きます。

https://appsync-immersionday.workshop.aws/

## 概要(ネタバレ注意)

- 各章立てと、概要を。※準備、片付けは割愛。

    - Lab 1. Hands-on with AppSync
        - マネジメントコンソールでAppsyncを作成し、GUI上のエディタでスキーマ定義、クエリ実行。
        - CDKでAppsyncを作成し、GUI上のエディタでスキーマ定義、クエリ実行。
        - サンプルアプリを立ち上げ、データを投入する実践的な動きを試せます。
    - Lab 2. Security
        - スキーマ・リゾルバを編集して、APIキーでの認証 → Cognitoユーザープールでの認証に置き換え。
        - 複数認証として、APIキー＋Cognitoの設定。
            - 試せませんでしたが、「AWS_IAM」「OPENID_CONNECT」も選択できる様子。
        - AWS WAFによるIPアドレス制御の設定
    - Lab 3. Common Design Patterns
        - Direct Lambda Resolversによるリゾルバの置き換え
            - VTLファイルで定義する必要のあるリゾルバが、Lambda(≒好きな言語)で記述できる！
        - Pipeline Resolverの構築 
            - ≒リゾルバの多段設定 
    - Lab 4. Operations and Management
        - X-Ray&CloudWatch Logsを有効化し、モニタリングを試せます。
        - ※ボリュームはちょっと少な目。

4時間ほどのボリュームで、完全に理解した！とまでは行かずとも、サービスの雰囲気が掴めてくるのが良いですね。
GraphQLを実案件で採用したことがないので、[blackbelt](https://www.slideshare.net/AmazonWebServicesJapan/20190821-aws-black-belt-online-seminar-aws-appsync)を一読したけど何も分からん、な人向きです。
英語分からんな場合でも、キャプチャやコマンドが多いので、Chrome翻訳で補完できる範囲かと思われます。というより私はそうでした。

## ハマったところ

- サンプルアプリのConfig(src/aws-exports.js)設定時の、相対パスが違う。
    - もう一か所あったので、私が作業ディレクトリを読み違えていたのかも。 
     
``` bash
# NG
cat << EOF > src/aws-exports.js
const awsmobile = {
  aws_appsync_graphqlEndpoint: '`jq -r .AppsyncWorkshopStack.GraphQLAPIURL ../appsync-workshop/output.json `',
  aws_appsync_apiKey: '`jq -r .AppsyncWorkshopStack.GraphQLAPIKEY ../appsync-workshop/output.json`',
  aws_appsync_authenticationType: 'API_KEY',
}

export default awsmobile
EOF

# OK(../→ ../../)
cat << EOF > src/aws-exports.js
const awsmobile = {
  aws_appsync_graphqlEndpoint: '`jq -r .AppsyncWorkshopStack.GraphQLAPIURL ../../appsync-workshop/output.json `',
  aws_appsync_apiKey: '`jq -r .AppsyncWorkshopStack.GraphQLAPIKEY ../../appsync-workshop/output.json`',
  aws_appsync_authenticationType: 'API_KEY',
}

export default awsmobile
EOF
```

- サンプルアプリがうまく立ち上がらない
    - エラーメッセージ抜粋

    ``` bash
    > application@0.1.0 start /home/ec2-user/environment/appsync-workshop/application
    > react-scripts start
    
    
    There might be a problem with the project dependency tree.
    It is likely not a bug in Create React App, but something you need to fix locally.

    The react-scripts package provided by Create React App requires a dependency:
    
      "jest": "26.6.0"

    ~~ 以下略 ~~

    ```

    - appsync-workshop/application 自体のnpmパッケージをいくら見てもわからん。。。と思いきや、一段上の階層のCDK実行環境 (appsync-workshop)のnode_modulesが悪さしてることが判明。
    - エラーメッセージの通りにjestのバージョンを指定したら直った。※以下npm全然分からん人向け
        - 該当のnode_modulesディレクトリを削除
        - package.jsonを以下のように書き換え
        
        ``` json
        {
          "name": "appsync-workshop",
          "version": "0.1.0",
          "bin": {
            "appsync-workshop": "bin/appsync-workshop.js"
          },
          "scripts": {
            "build": "echo \"The build step is not required when using JavaScript!\" && exit 0",
            "cdk": "cdk",
            "test": "jest"
          },
          "devDependencies": {
            "@aws-cdk/assert": "1.86.0",
            "aws-cdk": "1.86.0",
            "jest": "26.6.0"
          },
          "dependencies": {
            "@aws-cdk/aws-appsync": "1.86.0",
            "@aws-cdk/aws-cognito": "1.86.0",
            "@aws-cdk/aws-dynamodb": "1.86.0",
            "@aws-cdk/aws-lambda": "1.86.0",
            "@aws-cdk/aws-wafv2": "1.86.0",
            "@aws-cdk/core": "1.86.0"
          }
        }
        ```
 
        - "npm i"コマンドを実行することで、node_modulesを再設定される。
- Lab2の”Fine-Grained Access Control”設定以降から"listDataPoints"的なクエリが通らなくなる。
    - 後続のWAFの章でのクエリはうまくいくので、何らかの認証設定回り、リゾルバ周りの設定もれorコピペミスにも思えるのですが、時間切れでそのまま走り切ることに。
    - 成功した方はコメントお願いします！~~もう一回流す気力ないので~~ 
- CDKで作成したCognitoユーザプールのサインアップは認証コード受け取れるメアドの用意が必要なので、適当なのを入れてもダメな点に注意。
    - 登録先のユーザプールは自分管理、かつハンズオン後は削除するのでgmail登録する分にはそこまでシビアに扱わずとも良さそう。 

## おまけ

この章は、Workshopを試した結果生まれたポエムです。

### AppSync(というかResolver周り)への所感

- 大量のRESTへのクエリを、手前でプロキシ的に管理する仕組みは確かに便利そう。
- スキーマは良い。リゾルバの設定がVTL(Velocity Template Language)なの辛すぎないか。
    - ノーコードと言い張るには無理がある。API Gateway設定の辛い記憶が……
    - [ここ](https://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/tutorials.html)や[ここ]()にサンプルはあるが、独特のつらみがありそう。
    - [公式のコミュニティ](https://github.com/aws/aws-appsync-community)はしっかり見ておきたい。
- Direct Lambda Resolversで置き換えられるのが救いっちゃ救いなのだが、Lambda採用による課金が複雑になる&スロットリング管理が必要なのがペインポイントになりそう。
- せめてJSで書かせて……とGitHubのissuesを覗くと、計画はあった様子。過去形なのは、この記事を書く一週間ほど前に「やっぱダメかも(意訳)」とコメントを見つけたので……望み薄か……

https://github.com/aws/aws-appsync-community/issues/147#issuecomment-909750534

### 想定されるアンチパターン

- 「APIはインフラ担当だし、AWSなんだからインフラ屋に振ろう！という軽い感覚で分業すると失敗する予感。
    - この感覚が養えただけで本Workshopを試した意義がある。
- VTLファイルは単なるConfというより、簡易スクリプトなのでテスト戦略が試されそう。仮にチームのDev/Opsが分業されているとして、感覚的にはDev側が、少なくともResolverまで責任を持たないとダメそう。具体的には、下のような動きはかなりお勧めしません……

    - とりあえず正常系だけ通る大量のVTLをOps側に押し付ける。
    - 簡単なスクリプトなら大丈夫だろ！と、数行～数十行のbashしか書いたことないメンバをAppSync担当にする。
        - そもそもVTLでResolver書くのAppSyncだけなので、ここでしかノウハウが得られなさそう。少なくともapolloはJSっぽいし。[参考：Resolvers](https://www.apollographql.com/docs/apollo-server/data/resolvers/) 

- 私一人の愚痴でないことが、この画像でわかってちょっと安心
![55wdw5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528454/5a8652fd-7f72-2045-87b2-6039d34f3c2d.jpeg)


## まとめ

後半に謎の愚痴が入りましたが、GraphQLバリバリやりたいぜ！開発者はもちろん、チームで採用の機運がありそうで気になってるインフラエンジニアにもおススメなWorkshopなので、一度は入門してみることをおススメします。それでは。