Closed11
Serverless FrameworkでAWS AppSync上にGraphQL APIを構築したい(HTTPデータソース)
AWS AppSync JavaScript ResolverでHTTPデータソース(REST API)からデータを収集すると同じ仕様のAPIをServerless Frameworkで作りたい
Serverless FrameworkはYAMLで書いた定義と関連ファイル(今回はGraphQLスキーマとリゾルバ・関数のJSファイル)からCloudFormationのテンプレートファイルを生成してデプロイしてくれるフレームワークで、設定項目をいい感じに抽象化してくれる
もともとはAWS LambdaやGoogle Cloud Functions等のデプロイに使うのがメイン用途だけど、プラグイン(serverless-appsync-plugin)を使うことでAppSyncにも対応する
参考資料
最終成果物
雑感
- ほどよく抽象化されていて、リファレンスを見ながら書くことが困難でなかった
- 事前にCloudFormationで同じことをやっていたので、対応する設定がわかりやすかったのもある
- スキーマやリゾルバ、関数のコードを別ファイルで管理できるのでバージョン管理との相性がよい
- 参照の仕方も直感的で違和感がない
- デプロイの体験がよかった
- CloudFormationのスタックを作成する前に定義エラーがわかる
- 認証情報の設定からデプロイまで簡単なコマンドで完結する
serverless-appsync-pluginのJavaScript Resolver対応状況
- alphaのみ対応している
- issue
- ドキュメント
- 実装サンプル
pnpm i -D serverless-appsync-plugin@alpha
作業ログ
https://github.com/sid88in/serverless-appsync-plugin/blob/alpha/doc/resolvers.md を参考にテンプレートなしで構築(余計な要素を入れたくないので)
mkdir appsync-serverless-poc
cd appsync-serverless-poc
pnpm init
pnpm i -D serverless serverless-appsync-plugin@alpha @aws-appsync/utils @aws-appsync/eslint-plugin eslint prettier
serverless.yml
スキーマと各リゾルバ、関数は外部ファイルで定義する
schema.graphql
-
functions/
getTracksForHome.js
getAuthor.js
-
resolvers/
Query.tracksForHome.js
Track.author.js
serverless.yml
service: appsync-serverless-poc
frameworkVersion: "3"
configValidationMode: error
plugins:
- serverless-appsync-plugin
provider:
name: aws
region: ap-northeast-1
appSync:
name: AppSync Playground(serverless)
schema: schema.graphql
authentication:
type: API_KEY
dataSources:
catstronautsRestApi:
type: HTTP
config:
endpoint: https://odyssey-lift-off-rest-api.herokuapp.com
pipelineFunctions:
getTracksForHome:
dataSource: catstronautsRestApi
code: functions/getTracksForHome.js
getAuthor:
dataSource: catstronautsRestApi
code: functions/getAuthor.js
resolvers:
Query.tracksForHome:
code: resolvers/Query.tracksForHome.js
functions:
- getTracksForHome
Track.author:
code: resolvers/Track.author.js
functions:
- getAuthor
スキーマ
schema.graphql
type Author {
id: ID!
name: String!
photo: String
}
type Query {
tracksForHome: [Track!]!
}
type Track {
id: ID!
title: String!
author: Author!
thumbnail: String
length: Int
modulesCount: Int
}
関数
functions/getTracksForHome.js
import { util } from "@aws-appsync/utils";
export function request(ctx) {
return {
method: "GET",
params: {
headers: { "Content-Type": "application/json" },
},
resourcePath: "/tracks",
};
}
export function response(ctx) {
const { error, result } = ctx;
if (error) {
ctx.stash.errors = ctx.stash.errors ?? [];
ctx.stash.errors.push(ctx.error);
return util.appendError(error.message, error.type, result);
}
if (result.statusCode === 200) {
return JSON.parse(result.body);
} else {
return util.appendError(result.body, result.statusCode);
}
}
functions/getAuthor.js
import { util } from "@aws-appsync/utils";
export function request(ctx) {
return {
method: "GET",
params: {
headers: { "Content-Type": "application/json" },
},
resourcePath: `/author/${ctx.source.authorId}`,
};
}
export function response(ctx) {
const { error, result } = ctx;
if (error) {
ctx.stash.errors = ctx.stash.errors ?? [];
ctx.stash.errors.push(ctx.error);
return util.appendError(error.message, error.type, result);
}
if (result.statusCode === 200) {
return JSON.parse(result.body);
} else {
return util.appendError(result.body, result.statusCode);
}
}
リゾルバ
関数の結果をそのまま使うだけなので内容は共通
resolvers/Query.tracksForHome.js, resolvers/Track.author.js
export function request(ctx) {
return {};
}
export function response(ctx) {
return ctx.prev.result;
}
デプロイ
参考 https://www.serverless.com/framework/docs/providers/aws/guide/credentials/
認証方法は複数あるが、今回はserverless config credentials
コマンドを使ってみる
pnpm serverless config credentials --provider aws --key xxx --secret yyy
pnpm serverless deploy
動作確認
AppSyncのコンソールからAPI Keyを追加してクエリを実行
動いた
このスクラップは2023/02/15にクローズされました