[AWS×GraphQL] GraphQLでAWSLambdaをinvokeする feat.AWSAppSync

※この記事は [GraphQL Advent Calendar 2018](https://qiita.com/advent-calendar/2018/graphql) 21日目の記事です。
※この記事はAWS要素多めでお送り致しますので、ご了承ください。

# はじめに

いきなりですが皆さんはAWSLambdaをどのようにinvokeしていますか？
AWSのサービスからinvokeするなら

* APIGateway
* KinesisDataStreams
* SNS
* IoTCore
* DynamoDBStreams

あたりでしょうか？
個人的にAPIGatewayからLambdaをinvokeするパターンが一般的なのかな？と思っています。
APIGatewayを立てればRESTFullにLambdaをinvokeすることができます。
それかAWSSDKから直接Lambdaをinvokeするっていうパターンもあると思います。

## 今回の主役

今回の主役は **AWSAppSync** です！
簡単に説明すると、AWSAppSyncとはGraphQLを利用して、他のAWSサービスと連携をすることができるサービスです。
今回の記事のようにLambdaをinvokeしたり、DynamoDBのデータを直接操作したりすることができます。
AWS利用している方で「GraphQL始めたいなー」って方にはおすすめです。

<img width="525" alt="スクリーンショット 2018-12-06 11.21.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/95875/6b903b1b-2380-2a64-3d75-facb2a113d33.png">

## Lambdaの準備

今回の記事の内容から逸れてしまうので、この手順については省略します。
Lambdaのソースは何でもいいです。
AppSyncの設定をする前にデプロイしておいてください。
この記事で出てくるLambdaは、ランタイム `Node.js 8.10`です。
コードは以下の通り。 `event` の中身を出力して、 `event.input` を返すだけです。

```js
exports.handler = async (event) => {
  console.log(JSON.stringify(event));
  return event.input;
};
```

## AppSyncの設定

### DataSourcesの追加

LambdaをAppSyncのDataSourcesとして追加する必要があります。
DataSourcesにはLambdaはもちろん、DynamoDBのテーブルなどを設定することができます。
DataSourcesは要するに、GraphQLのSchemaの定義をする際に、その処理の対象となるリソースのことを指します。
この処理はこのLambdaをinvokeする、この処理はこのDynamoDBのテーブルを操作するといった形です。

では追加していきましょう。
DateSourcesコンソール画面左上の「Create data source」から
<img width="1338" alt="AWS AppSync Console 2018-12-06 13-08-29.png" src="https://qiita-image-store.s3.amazonaws.com/0/95875/3c3440dd-c820-98da-c6dd-0e6f7d33ce17.png">

必要項目を入力・選択して「Create」で追加完了です
<img width="1336" alt="AWS AppSync Console 2018-12-06 13-11-45.png" src="https://qiita-image-store.s3.amazonaws.com/0/95875/aa143e99-486c-bfb5-fb2d-38dc2f78715d.png">

### Schemaの定義を書く

Schemaコンソール画面から下記を追加する

```

input InvokeLambdaFunctionInput {
  id: String!
  value: String!
}

type Mutation {
  // Mutationの一番下の行に追加
  invokeLambdaFunction(input: InvokeLambdaFunctionInput!): AWSJSON
}
```

### Resolversの設定

先程追加したSchemaのDataSourceを選択します。ここでようやくLambdaと紐付ける形になります。
右ペインの「Resolvers」欄から「invokeLambdaFunction」の「Attach」を選択
<img width="542" alt="AWS AppSync Console 2018-12-06 13-37-24.png" src="https://qiita-image-store.s3.amazonaws.com/0/95875/c68a6992-5ffc-b233-2b1b-ed5c499e5d62.png">

「Data source name」で先程追加したDataSourceを選択。あとはデフォルトのまま「Save Resolver」を選択
<img width="1334" alt="AWS AppSync Console 2018-12-06 13-39-23.png" src="https://qiita-image-store.s3.amazonaws.com/0/95875/6a6e7b5f-c5e2-5b09-47a5-f8b0ffa144f3.png">

これで準備が整いました

## 実際に試してみましょう

Queriesのコンソール画面から試すことができます。
左ペインに下記のように入力します。

```
mutation invoke {
  invokeLambdaFunction (input: {
    id: "test invoke"
    value: "test desuyo !!!"
  })
}
```

オレンジの実行ボタンをクリックするとこのように返ってきます。

```
{
  "data": {
    "invokeLambdaFunction": "{\"id\":\"test invoke\",\"value\":\"test desuyo !!!\"}"
  }
}
```

`"{\"id\":\"test invoke\",\"value\":\"test desuyo !!!\"}"`　という型がAWSJSONという型になります。
実際に使う時はJSONに変換する必要があったりするのでご注意を。

## さいごに

はい。これでGraphQLからLambdaをinvokeすることができました！やったね！！！
個人的にはAPIGatewayを立てる手間よりもAppSyncでやったほうが楽でした。AuthなどについてもAppSyncがAPIKey認証や、Cognito認証をするように設定することもできるので心配はないです。
WebアプリからAppSyncを使うには `AWS Amplify` がおすすめです。これを利用すると割と簡単にAppSyncで定義したGraphQLを利用することができます。
これでさらにLambdaが便利なものになりましたね！ではまた！！