スポンサーリンク
概要
AWS Lambda上でGraphQLを使用したAPIを公開するための実装方法などの紹介。
スポンサーリンク
前提
下記記事で紹介した方法でAWS Lambda用のTypescriptのコード雛形を作成する。
参照
下記の環境で実施
macOS 10.15.2
VSCode 1.41.1
下記をインストール済とする
node.js (v12.14.0)
yarn (v1.17.3)
なお、GraphQL自体の細かい仕様や説明は省略する。
必要な場合ググれば、GraphQLに関しての説明は多く見つかると思うのでそちらを参照してほしい。
スポンサーリンク
API定義
今回は下記の2種類のAPIをGraphQLで実装する。
スキーマ名 | 引数 | 説明 |
---|---|---|
user | id:string | 指定されたIDのユーザ情報を取得 |
users | なし | 全ユーザ情報を取得 |
ユーザ情報は下記を持つ
パラメータ名 | 型 | 説明 |
---|---|---|
id | String(ID) | ユニークID |
name | String | 名前 |
age | Int | 年齢 |
手順
準備
GrapghQL用モジュールのインストールを行う。
1 |
yarn add graphql |
実装
個々のの説明は順を追って行うが、全体のコードを下記に示す。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
import * as lambda from 'aws-lambda'; import { graphql, buildSchema } from 'graphql'; const typeDefs = ` type Query { user(id: Int!): User users: [User] } type User { id: ID! name: String! age: Int } `; interface User { id: string; name: string; age: number; } const resolvers = { user: args => getUserById(args.id), users: () => getUsers() }; function getUserById(id: string): Promise<User> { return new Promise((resolve, reject) =>; { const user = { id: id, name: 'test', age: 12 }; resolve(user); }); } function getUsers(): Promise<User[]> { return new Promise((resolve, reject) =>; { const users = [ { id: '1', name: 'test1', age: 12 }, { id: '2', name: 'test2', age: 45 } ]; resolve(users); }); } export const handler = async ( event: any, context: lambda.Context, callback: lambda.Callback ) =>; { //クエリの実行 const result = await graphql(buildSchema(typeDefs), event.query, resolvers); callback(null, result); }; |
スキーマおよびリゾルバの定義
GrapghQLで必要となるスキーマ(typeDefs)とリゾルバ(resolvers)を定義する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
const typeDefs = ` type Query { user(id: Int!): User users: [User] } type User { id: ID! name: String! age: Int } `; const resolvers = { user: args => getUserById(args.id), users: () => getUsers() }; |
リゾルバには各スキーマと実際のプログラムコードの紐付けを行う。
userのリクエストが来た場合、getUserById関数
usersの場合、getUsers関数が呼び出されるように紐付けしている。
各関数の実装
リゾルバに紐づけられた関数の実装を行う。
今回はサンプルとして固定値を戻り値として返すが実際の場合は、DynamoやRDSなどからデータを取得する処理を実装する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
interface User { id: string; name: string; age: number; } function getUserById(id: string): Promise<User> { return new Promise((resolve, reject) => { const user = { id: id, name: 'test', age: 12 }; resolve(user); }); } function getUsers(): Promise<User[]> { return new Promise((resolve, reject) => { const users = [ { id: '1', name: 'test1', age: 12 }, { id: '2', name: 'test2', age: 45 } ]; resolve(users); }); } |
ハンドラ
Lambdaのハンドラ内でスキーマ及びリゾルバとクエリを渡して処理を実行する。
1 2 3 4 5 6 7 8 9 |
export const handler = async ( event: any, context: lambda.Context, callback: lambda.Callback ) =>; { //クエリの実行 const result = await graphql(buildSchema(typeDefs), event.query, resolvers); callback(null, result); }; |
上記のコードをLambda上にデプロイすればAPI側の開発は完了。
リクエスト
クライアント側のリクエスト処理方法に関してはPOST及びGETでの対応が可能。
ただし、GETの場合にはAPIGatewayでの変換が必要となる。
POSTリクエストで投げる場合
下記のようにPOSTメソッドでJSONパラメータとして渡す。
1 2 3 |
{ "query": "{user(id:10){id name age}}" } |
下記のような形でレスポンスが帰ってくる
1 2 3 4 5 6 7 8 9 |
{ "data": { "user": { "id": "10", "name": "test", "age": 12 } } } |
GETリクエストで投げる場合
前述の通り、APIGateway側での対応が必要となる。
GETリクエストのURLパラメータをPOSTの時のJSON形式に変換することで対応が可能になる。
メソッドリクエストにパラメータを追加
URLクエリ文字列パラメータに下記のようにqueryといったパラメータを追加する
JSONマッピング
統合リクエストのマッピングテンプレートに下記を追加する。
Content-type:application/jsonに対して下記の値を設定する。
1 2 3 |
{ "query": "$input.params('query')" } |
GETリクエストの場合は、下記のようにqueryパラメータにデータを渡す。
https://xxxxxxxx?query={user(id:10){id name age}}
まとめ
AWS LambdaでGrapghQLを使ったAPIを作成する方法を紹介した。
GraphQL自体はREST-APIと比較すると知名度ではまだまだだが、これから徐々に普及していくのではと期待できるため、これを期に学ぶ事も大事だと思う。
個人的には、オライリーの初めてのGraphQLがわかりやすく、学ぶのにオススメである。