基本的にはこちらを参考にしました。
How to Make a Serverless GraphQL API using Lambda and DynamoDB
https://www.serverless.com/blog/make-serverless-graphql-api-using-lambda-dynamodb
ただし、イベントハンドラをasync
関数にしたり、GETリクエストではなくPOSTリクエストを受け付けるようにしています。
また、上記では、GraphQLSchema()
などを使っていますが、スキーマの定義などに関しては、GraphQL.js公式ページを参考にしました。
Getting Started With GraphQL.js
https://graphql.org/graphql-js/
あれ、「How to Make a Serverless GraphQL API」の方、ほとんど参考にしてない?笑
結論
特に難しいことはなく、POSTリクエストで送った値をevent.body
から取り出して、graphql()
の第二引数に渡すだけ。
コマンドやコード
$ sls create -t aws-nodejs-typescript -p sample-graphql-lambda-api
$ yarn init -y
$ yarn
$ yarn add graphql
// 下記追加
// その他、region(ap-northeast-1など)を追加するのを忘れずに。
functions: {
query: {
handler: "handler.query",
events: [
{
http: {
method: "post",
path: "graphql",
},
},
],
},
}
//import { APIGatewayProxyHandler } from "aws-lambda";
import "source-map-support/register";
import {
graphql,
buildSchema
} from "graphql";
const schema = buildSchema(`
type Query {
hello: String
}
`);
const root = {
hello: () => {
return "Hello world!";
},
};
export const query = async (event) => {
const query = event.body;
const result = await graphql(schema, query, root);
const response = {
statusCode: 200,
body: JSON.stringify(result),
};
return response;
};
$ curl --request POST --header "Content-Type: application/json" --data "{ hello }" '{Lambda関数のエンドポイント }}'
{"data":{"hello":"Hello world!"}}
おしまい。
[番外編]リゾルバーで引数を取り出す時の{ person }
ってなんだ?
引数を足したり、複数のデータを返す場合。
const schema = buildSchema(`
type Query {
hello(person: String): Text
}
type Text {
text1: String,
text2: String
}
`)
const root = {
hello: ({ person }) => {
return { text1: `${person}さん、こんばんは!!!!!!!!!!`, text2: "おはようございます" }
}
}
$ curl --request POST --header "Content-Type: application/json" --data "{ hello(person: \"tarou\"){text1 text2 }}" '{Lambda関数のエンドポイント }'
{"data":{"hello":{"text1":"tarouさん、こんばんは!!!!!!!!!!","text2":"おはようございます"}}}
root
オブジェクトにクエリごとに設定する関数で引数を取り出す時、なんでperson
ではなく{ person }
なのかと思っていた。
これはJSの記法で、分割代入らしい。
var origin = {a:1, b:2, c:3};
var {a} = origin;
var {b} = origin;
var {c} = origin;
console.log('a = ' + a); // a = 1
console.log('b = ' + b); // b = 2
console.log('c = ' + c); // c = 3
JavaScriptの変数名が中括弧で囲まれた変数宣言
オブジェクトから{}
の中で指定したプロパティの値を取り出して、それを同名の変数に代入してるらしい。
つまり、root
オブジェクトでクエリごとに割り振る関数の引数には、オブジェクトが渡されているらしい。
→そういえば、curl
でも、--data "{ hello(person: \"tarou\"){text1 text2 }}"
という感じで、person
keyを渡していたんだった(これがないとエラーになる)
ちなみに、「root
オブジェクトでクエリごとに割り振る関数」は'resolver function'というらしい。
// The root provides a resolver function for each API endpoint
var root = {
hello: () => {
return 'Hello world!';
},
};
Getting Started With GraphQL.js
番外編が長い。
別途、AppSyncってなんだ?GraphQL使うなら、API Gatewayじゃなくてこっち使った方がいいのかな。