AppSyncのHTTPデータソースを使って、外部サービスとのAPI連携をしてみた🌈

AppSyncのHTTPデータソースを使って、外部サービスとのAPI連携をしてみた🌈

こんにちは!

AppSync でデータソースに HTTP エンドポイントを選択する場合、AWS リソース以外で何かしらの API を実行して情報を取得してみたいと思ったことはありませんか?

今回は AppSync のデータソース応用編ということで、開発者用に公開されているAPI、OpenWeatherMap を利用して天気予報の情報を取得したいと思います。

※以降の手順は OpenWeatherMap に登録して API キーを作成しているという前提のもと行っております。

想定する読者

  • AppSync に興味があるヒト
  • HTTP データソースを使ってみたいヒト
  • AppSync 経由で REST API を実行したいヒト

はじめに

GraphQL に外部サービスの API を連携したい場合においても、マネージドサービスの AppSync なら簡単に設定することができます。

今回の記事は AppSync や GraphQL を学び始めたばかりの方でも、わかりやすいものとなっておりますので、ぜひ参考にしてみてください。

データソースは HTTP エンドポイント

API を利用する場合は、まず AppSync のデータソースで HTTP エンドポイントを作成いたします。この際に OpenWheterMap のエンドポイントを設定してください。

CloudFormation では以下のように記述します。

Resources:
  DataSource:
    Type: AWS::AppSync::DataSource
    Properties:
      ApiId: !GetAtt GraphQLApi.ApiId
      Name: WeatherAPI
      Type: HTTP
      HttpConfig:
        Endpoint: http://api.openweathermap.org

シンプルに HTTP エンドポイントの URL を指定するだけとなります。

なお、データソースのリソースでは パラメータ「Type」によって記述するものが変わります。今回の場合は HTTP を指定していますので、HttpConfig を使うことになります。

スキーマ定義

今回は指定した都市の気象情報を取得したいため、以下のようにスキーマを定義します。

type Query {
	whatTheWeather(city: String!): Weather
}

type Weather {
	city: String
	weather: String
	description: String
	temp: Float
}

schema {
	query: Query
}

クエリは1つだけ定義しました。そして取得した情報から、都市名・天気・概要・気温を表示できるようにしました。

VTL(リクエスト/レスポンス)

スキーマを定義したら、Query 型の whatTheWeather フィールドに対してリゾルバーをアタッチします。その次に VTL を記述していきましょう。

リクエストマッピングテンプレートは以下のように記述します。

{
    "version": "2018-05-29",
    "method": "GET",
    "resourcePath": "/data/2.5/weather",
    "params":{
        "query": {
            "q": "$context.args.city",
            "APPID": "API_KEY"
        },
        "headers": {
            "Content-Type": "application/json"
        }
    }
}

API の仕様に従い、パスは /data/2.5/weather に向け、パラメータには都市の名前と API キーを指定いたします。上述のコードにある API_KEY には、OpenWheterMap で作成した API キーの文字列を貼り付けてください。

では最後にレスポンスマッピングテンプレートを以下のように記述します。

#if($ctx.result.statusCode == 200)
#set($response = $util.parseJson($ctx.result.body))
#set($result = {
 "city": $response.name,
 "weather": $response.weather[0].main,
 "description": $response.weather[0].description,
 "temp": $response.main.temp
})
$util.toJson($result)
#else
$util.error($ctx.result.body)
#end

取得したい情報の値を、レスポンスでセットしております。

API のリクエストやレスポンスをカスタマイズする場合は、OpenWheterMap のドキュメントをご覧ください。今回利用しているのは、Current weather data という API となります。

クエリを実行

上記の設定が完了したら、実際にクエリを実行してみましょう。

無事成功です!これで現在の都市の天気と気温がわかりました!

エラーの場合も観察してみましょう。存在しない都市名を指定してクエリを実行してみます。

ステータスコードとエラーメッセージが返されました。想定通りのレスポンスとなります。

ちなみに気温の単位はケルビンですので、上記の場合だと約11°ぐらいだということがわかります。

さて、これまでの手順を見ていかがでしたでしょうか?かなり簡単に AppSync から API を実行できたかと思います。この記事がお読み頂いた方の参考になれば幸いです。

関連記事

まとめ

データソースとしては主に DynamoDB や Lambda 関数を利用されるケースが多いかと思いますが、データソースとして選択できない AWSリソースや何かのAPI と連携に必要なときのために「HTTP エンドポイント」という選択肢がありますので、そういった要件の場合はぜひ活用してみてください!

このブログでは、GraphQL や GraphQL のマネージドサービスである AWS AppSync の記事をどんどん公開しておりますので、ご興味のある方はほかの記事もご覧いただければと思います。

AppSync に関する開発は、お気軽にお問い合わせください。