LoginSignup
54
48

More than 5 years have passed since last update.

API Gatewayを利用して既存APIから返却されるJSONの構成を変えてクライアントに返却する

Posted at

API GatewayのModelsとMapingテンプレートを利用することで既存APIから返却されるJSONの構成を変えてクライアントに返却できます。その内容について記載されたWalkthrough: API Gateway, Models, and Mapping Templatesを試してみたのでメモ

参考

なお、Lambdaとの連携は以下にまとめました。

API Gatewayを使ってアクセスキー認証でLambdaを実行する

やること

以下のようなJSONを返却するAPIがあります。(実際に以下のURLで動きます)

$curl http://petstore-demo-endpoint.execute-api.com/petstore/pets
[
  {
    "id": 1,
    "type": "dog",
    "price": 249.99
  },
  {
    "id": 2,
    "type": "cat",
    "price": 124.99
  },
  {
    "id": 3,
    "type": "fish",
    "price": 0.99
  }
]%

上記をAPIをAPI Gatewayを経由して呼び出すことで以下のようにKeyを変更して返却されるようにします。(Ver.1)

[
  {
    "number": 1,
    "class": "dog",
    "salesPrice": 249.99
  },
  {
    "number": 2,
    "class": "cat",
    "salesPrice": 124.99
  },
  {
    "number": 3,
    "class": "fish",
    "salesPrice": 0.99
  }
]

また、以下のように構成を変えてみます(Ver.2)

[
  {
    "description": "Item 1 is a dog.",
    "askingPrice": 249.99
  },
  {
    "description": "Item 2 is a cat.",
    "askingPrice": 124.99
  },
  {
    "description": "Item 3 is a fish.",
    "askingPrice": 0.99
  }
]

最後の例ではそれぞれのアイテムを1行にまとめてみます(Ver.3)

{
  "listings": [
    "Item 1 is a dog. The asking price is 249.99.",
    "Item 2 is a cat. The asking price is 124.99.",
    "Item 3 is a fish. The asking price is 0.99."
  ]
}

リージョンの設定

API Gatewayは2015年7月11日現在はtokyoリージョンで使えないため、リージョンはUS-EAST(N.Varginia)に設定します

APIの作成

まずはAPIGatewayの画面を開いてAPIを作成します。

初めての場合、Get Startedを選択し、すでにAPIがある場合、create APIを選択します。選択すると以下のような画面となります。

Screen Shot 2015-07-11 at 3.49.38 PM.png

作成するAPI名は TestAPIGateway としました。設定後、 Create API でAPIを作成します。

[Ver.1]リソースの作成

次にリソースを作成します。リソースはアクセスする時のURLのパスの一部になります。 API作成後、以下のような画面になると思うので、 Create Resource を選択します。

Screen Shot 2015-07-11 at 3.50.41 PM.png

次の画面でResource名を決定します。 
本例では changekey としました。

Screen Shot 2015-07-11 at 3.51.53 PM.png

指定後、 Create Resource でリソースを作成します。

[Ver.1]メソッドの作成

次に上記リソースへのアクセスがあった際にどのような動作をするか決定するメソッドを設定します。

Create Method ボタンを選択すると以下のように右側にどのHTTPメソッドを利用するかのセレクトとボックスが表示されます。

Screen Shot 2015-07-11 at 3.56.28 PM.png

今回の例ではGETメソッドを選択し、選択後にセレクトボックス右のチェック?ボタンを選択すると決定できます。

選択後、少し待つと登録が完了し、右ペインにメソッドのセットアップを行うための画面が表示されます。

Screen Shot 2015-07-11 at 4.00.13 PM.png

今回はAPI呼び出し時に http://petstore-demo-endpoint.execute-api.com/petstore/pets にリバースプロキシしたいので上記のように設定します。

設定が完了したら Save を選択します。

[Ver.1]テストする

作成後、以下のような画面になり、APIが呼ばれた際にどのような流れでリクエストが流れるが確認できます。

Screen Shot 2015-07-11 at 4.08.17 PM.png

右のペインのTEST(稲妻アイコン)を選択することでテストができます。

TEST(稲妻アイコン)を選択後、再度存在するTEST(稲妻アイコン)を選択することでリクエストが呼ばれた際のレスポンスを確認できます。

Screen Shot 2015-07-11 at 4.10.35 PM.png

返却されるJSONの編集はしていないため、直接呼ばれた時と同じJSONが返却されることが確認できました。

[Ver.1]モデルの作成

モデルではJSONをJSON Schemeによってデータの定義をします。APIGatewayによって返却される際のJSONの定義を行うモデルを作成します。

Amazon API Gatewayというロゴが表示された部分を選択します。
画面遷移後、作成したAPI一覧が確認できるので本例で作成したAPIの 2 Models となっているリンクを選択します。

選択後、モデルを作成する画面になるので Create ボタンを選択します。

Screen Shot 2015-07-11 at 5.02.37 PM.png

設定は上記画面のように以下のような設定としました。

  • Model name->PetsModelChangedKey
  • Content type->application/json
  • Model Schema->下部参照
ModelSchema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "PetsModelChangedKey",
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "number": { "type": "integer" },
      "class": { "type": "string" },
      "salesPrice": { "type": "number" }
    }
  }
}

最初の例ではKey名を変えたいのでid->number,type->class,price->salesPriceとそれぞれ変更するKey名のJSON定義となっています。構造は変わってないので変更されていません。

[Ver.1]モデルとメソッドの紐付け

作成したモデルとメソッドの紐付けを行います。

再度、Amazon API Gatewayというロゴが表示された部分を選択します。
画面遷移後、本例で作成したAPIの 2 Resources となっているリンクを選択します。

右側の /changekey/GET のリンクをクリックし、先ほどテストした時の画面を表示し、 Method Response のリンクを選択します。ここで返却するJSONの定義を記載します。

  • 200の横の矢印ボタンを選択
  • Response Models for 200の横の鉛筆アイコンを選択
  • セレクトボックスから先ほど作成したPetsModelChangedKeyモデルを選択
  • セレクトボックスの隣のチェックアイコン?を選択

Screen Shot 2015-07-11 at 5.09.42 PM.png

次に Integration Response リンクを選択します。ここでは取得したJSONを返却するJSONにどのようにマッピングするか定義します。

  • 200の横の矢印ボタンを選択
  • 画面下部のTemplate Mappingsの位置にスクロールし、Content Type横の鉛筆アイコンを選択
  • Output passthroughのチェックを外す
  • Generate template from modelのセレクトボックスから PetsModelChangedKeyを選択
  • マッピングが表示される。変数を参照する形になっていないので以下のように少し変更
  • Content Type横のチェックアイコン?を選択
#set($inputRoot = $input.path('$'))
[
#foreach($elem in $inputRoot)
  {
    "number": $elem.id,
    "class": "$elem.type",
    "salesPrice": $elem.price 
  }#if($foreach.hasNext),#end

#end
]

Screen Shot 2015-07-11 at 6.09.06 PM.png

[Ver.1]結果を確認

準備ができたのでTEST(稲妻アイコン)を選択して返却されるJSONが変更されているか確認します。

成功していれば以下のようなレスポンスボディとなっていることが確認できます。

[
  {
    "number": 1,
    "class": "dog",
    "salesPrice": 249.99
  },
  {
    "number": 2,
    "class": "cat",
    "salesPrice": 124.99
  },
  {
    "number": 3,
    "class": "fish",
    "salesPrice": 0.99
  }
]

[Ver.2]対応方法概要

同じ要領でやっていきます。

  • 任意の名称でリソースを作成
  • Getメソッドを作成
  • モデルを作成。以下のようにする。以下例の場合、モデル名は「PetsModelFlattenSome」とする
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "PetsModelFlattenSome",
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "description": { "type": "string" },
      "askingPrice": { "type": "number" }    
    }
  }
}
  • モデルとメソッドを紐付ける
  • マッピングでは以下を指定
#set($inputRoot = $input.path('$'))
[
#foreach($elem in $inputRoot)
  {
    "description" : "Item $elem.id is a $elem.type.",
    "askingPrice" : $elem.price
  }#if($foreach.hasNext),#end

#end
]

テストを実行し、以下のようなレスポンスボディとなっていればOKです。

[
  {
    "description": "Item 1 is a dog.",
    "askingPrice": 249.99
  },
  {
    "description": "Item 2 is a cat.",
    "askingPrice": 124.99
  },
  {
    "description": "Item 3 is a fish.",
    "askingPrice": 0.99
  }
]

[Ver.3]対応方法概要

同じ要領でやっていきます。

  • 任意の名称でリソースを作成
  • Getメソッドを作成
  • モデルを作成。以下のようにする。以下例の場合、モデル名は「PetsModelFlattenAll」とする
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "PetsModelFlattenAll",
  "type": "object",
  "properties": {
    "listings": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  }
}
  • モデルとメソッドを紐付ける
  • マッピングでは以下を指定
#set($inputRoot = $input.path('$'))
{
  "listings" : [
#foreach($elem in $inputRoot)
    "Item number $elem.id is a $elem.type. The asking price is $elem.price."#if($foreach.hasNext),#end

#end
  ]
}

テストを実行し、以下のようなレスポンスボディとなっていればOKです。

{
  "listings": [
    "Item number 1 is a dog. The asking price is 249.99.",
    "Item number 2 is a cat. The asking price is 124.99.",
    "Item number 3 is a fish. The asking price is 0.99."
  ]
}

デプロイする

まだデプロイをしていないのでインターネットから上記APIを叩くことができません。デプロイするためには Deploy API ボタンを選択し、任意のステージにデプロイすればOKです。ステージの画面で実際にアクセスするURLも表示されます。

ただし、この状態でデプロイすると特に認証なくアクセスできるのでIAMもしくはアクセスキーによる認証をした方が良いと思います アクセスキーによる認証は以下に書きました。

API Gatewayを使ってアクセスキー認証でLambdaを実行する

すでに作成されたメソッドで認証をアクセスキーにする場合、 テストができる画面で Method Request リンクを選択し、API Key RequiredをtrueにすればOKでした。リソースごとに認証有無及び認証方法も変えれるようです。

掃除する

テストなどができる画面などリソースを操作する画面の右上に Delete API ボタンがあるのでこれでAPIごと削除可能です。

54
48
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
54
48