Closed11

AWS AppSync JavaScript ResolverでHTTPデータソース(REST API)からデータを収集する

qmotasqmotas
qmotasqmotas

ハマったポイントとか

  • HTTPデータソースから取得した結果はctx.result.bodyから取り出す(レスポンスボディだからそれはそう)
  • ctx.result.bodyは文字列なのでJSON.parse()する必要がある
  • HTTPデータソースにAPI Gatewayで作成したAPIを使う場合、エンドポイントのURLはステージ名(/devとか)を含まないものにする必要がある
    • トラブルシュート時にREST APIへの疎通を確認したくてAPI Gatewayでモックを作って叩こうとしたが、エンドポイントにhttps://xxx.amazonaws.com/devまでのURLを指定したらtemplate transformation yelded an empty responseというエラーになった
  • 親リゾルバの結果はctx.sourceに格納されている
qmotasqmotas

Pipeline Resolver

https://aws.amazon.com/jp/blogs/news/getting-started-with-javascript-resolvers-in-aws-appsync-graphql-apis/

  • Pipeline Resolverは以下の順で処理を実行して最終的な結果をリゾルバの戻り値として使う
    • 前処理
    • 最大10件のFunction
    • 後処理
  • AppSyncのコンソールでスキーマのフィールドにリゾルバをアタッチすると、Pipeline Resolverになる
  • 任意のデータソースに対する処理を関数(Function)として定義しておいて、Pipeline Resolverから参照する
qmotasqmotas

題材

  • Apollo Odysseyのアプリ(Catstronauts)のバックエンドの一部をAppSyncで再現する

type Query {
  tracksForHome: [Track!]!
}

type Track {
  id: ID!
  title: String!
  author: Author!
  thumbnail: String
  length: Int
  modulesCount: Int
}

type Author {
  id: ID!
  name: String!
  photo: String
}

qmotasqmotas

APIの作成

  • AppSyncのコンソールからAPIを作成
  • 一から構築を選択して開始
    • とりあえず動くAPIを作りたい場合はサンプルプロジェクトから開始するからイベントアプリなどを選択して作成するとDynamoDBをリソースとして直接読み書きするAPIが作れる

qmotasqmotas

データソースの定義

  • コンソールの左側からデータソース > データソースを作成
  • 任意のデータソース名を入力
    • catstronauts_rest_apiとした
  • データソースタイプはHTTPエンドポイント
  • HTTPエンドポイントはAPIのベースURL

qmotasqmotas

関数の定義

REST APIを叩いて結果を戻す関数を作成する

  • コンソールの左側から関数 > 関数を作成
  • 作成したデータソースを選択
  • 関数名を入力
    • Apollo Odysseyに倣ってgetTracksForHomeとした

関数コード

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);
  }
}
qmotasqmotas

スキーマにリゾルバをアタッチ

スキーマタブで画面右側、リゾルバーペインからtracksForHome: [Track!]!クエリのアタッチを押す

右下の方にある関数を追加 > getTracksForHomeを選択

関数が追加される

画面右上の作成を押して保存するとPipelineリゾルバがクエリにアタッチされた状態になる

qmotasqmotas

クエリを実行してみる

Authorのリゾルバは未作成なので外してクエリを投げると結果が戻ってくる

qmotasqmotas

ネストされたフィールドのリゾルバを書く

関数getAuthorを追加する

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);
  }
}

動いた

このスクラップは2023/01/06にクローズされました