Upgrade to Pro — share decks privately, control downloads, hide ads and more …

API GatewyとS3で作るサーバレス・スタブ

API GatewyとS3で作るサーバレス・スタブ

(⭐)は、改ページマーク

それでは、「API GatewayとS3で作る サーバレス・スタブAPI」ということで発表させてもらいます
(⭐)
まずは、自己紹介を、曲とか作ったりSIやったりするプログラマです。
よく使うプログラミング言語はJavaとnode.jsです。
ニコニコ動画とかサウンドクラウドで曲を公開したりしているので、もしよければよろしくお願いします。
(⭐)
今日は次の流れで紹介させてもらおうと思います、
資料は結構細々としたことを書いたつもりなのですが、10分だと少し話しきれないと思うので、
今日はここで概要を話しつつ、詳細は後ほど公開する資料を参照していただければと思います。
(⭐)
あるある事例、ということで、今日この仕組みを作ろうと思った前提を話させてもらいます
(⭐)
開発をしようと思っているときに結構こういうことありませんか?
複数のREST APIを連携するシステムを作りたいんだけど、
納期が切迫してるので、各システムを並行で開発してほしいんだけど、
お互いにできるのを待ってたら互いに待ちが発生するので
各APIの仕様書はできてるから、それを参考に開発してね。みたいな。
(⭐)
なら、開発現場では対向サーバのスタブとか作って開発やテストをしてみましょう。
ということになるんですが、これも結構サーバを準備したりデプロイしたり、HTTPS対応が手間、
とか、色々ありますよね。
(⭐)
ということで、こんなことをやってみたいと思いました。
(⭐)
できるだけ簡素に作りたいので、Lambdaなどでのコーディングはできるだけせずに、
サーバレスで、HTTPSに対応した、REST APIスタブを
できるだけ楽に作りたい。
(⭐)
完成イメージはこんな感じです。
(⭐)
まず、開発サーバから、API GatewayというAWSのサービスにREST API形式のリクエストを投げると
(⭐)
API Gatewayが良い感じにリクエストを解釈してくれて、
S3というストレージに保存されたファイルを取得します。
ヘッダや、リクエストパラメータからこの取得するファイルは切り替えられるんですが、今回は単純にリクエストパスを元にこの取得するファイルを切り替えます。
(⭐)
そして、取得したファイルを元に、HTTP形式のレスポンスヘッダや、ボディを設定して、
HTTPレスポンスを返してくれる。
そんな感じのものを作って行きたいと思いまーす。
(⭐)
じゃあ、まず、API GatewayとS3ってそもそもなによって話から入っていこうと思います。
(⭐)
Amazon API GatewayはAWS上でAPIの作成と、管理が行えるサービス。
ざっくりいうと、このサービスで作成したAPIにリクエストすると、
AWSの他サービスと連動させて、そのサービスの処理結果をAPIのレスポンスとして返すことができます。
(⭐)
S3は、AWS上で提供されるストレージサービスです。
ただのファイルストレージとしてだけでなく、AWSの他サービスと連携してファイルをやりとりすることができます。
便利ですねー。
(⭐)
S3は、単にファイルストレージなので、ファイルの出し入れができる。というのはわかるのですが、
API Gatewayってどんな感じに動いてるの?というのを説明していこうと思います。
(⭐)
まずは、APIのプロジェクト的なものを作成して
(⭐)
そのAPIのエンドポイントを作成します。
エンドポイントなので、この赤いところのように、あるAPIにアクセスするためのパスを切るわけですね。
クライアントはここで、定義したパスにリクエストを投げることになります。
(⭐)
で、そのエンドポイントがどんなリクエストヘッダや、リクエストパラメータを受け付けるのかを、この「メソッドリクエスト」で設定されていて、
クライアントからのリクエストはここで解釈されます。
(⭐)
その後、リクエストは、この「統合リクエスト」の設定を通じて他のAWSサービス向けリクエストに変換・マッピングされます。
(⭐)
他のAWSサービス、例えばS3などがなどがファイルを取得して、その結果をAPI Gatewayにレスポンスします。
(⭐)
そのS3からのレスンポンスは、API Gatewayに渡されて、API GatewayはS3から取得した内容を、
クライアントに返すためにの、レスポンスヘッダやボディにマッピングします。
(⭐)
そして、最後に、メソッドレスポンスでこのAPIがどんなレスポンスを、どんな形式で返すかを定義してあげて、クライアントにレスポンスが帰っていきます。
(⭐)
では、実際にこのAPI Gatewayを使って、スタブサーバを作ってみましょう。
(⭐)
まず、APIを作成していきます。新しいREST APIとしてAPIを作成します。
(⭐)
次に、APIのエンドポイントを作成します。
今回は、API Gatewayにはプロキシとして動作してもらいます。
通常、APIのエンドポイントごとに、作成する必要があります。

ですが、Proxyとして設定することで、一旦どんなパスへのリクエストも受け付けて、
その受け付けたパスを元に、良い感じにS3のファイルとマッチングさせて、レスポンスを返すことができます。
(⭐)
ここで、統合タイプを設定する必要があるのですが、これは後ほど細かく設定するので一旦スキップします。
具体的には、こんな感じの内容で適当に設定します。
(⭐)
では、さっそくプロキシのエンドポイントに向けられたリクエストを、S3にへのリクエストに変換してみようと思います。
「統合リクエスト」を選択します。
(⭐)
統合リクエストでは、API Gateway向けのリクエストからS3向けのファイル取得リクエストに変換します。
(⭐)
こんな感じで、連携先をS3に設定してー、 API GatewayからS3へのリクエストはファイル取得なのでGETメソッドで行うようにしてー。
(⭐)
API Gatewayへのリクエストパスを、S3のファイルパスにマッピングします。
S3へのアクセス権もここで設定してあげます。
この「proxy_param.json」となっているところが、S3上のファイル名ですね
proxy_paramという変数の値は、API Gatewayへのリクエストパスから持ってくることになります。
(⭐)
じゃあ、その「proxy_param」っていう変数と、API Gatewayへのリクエストパスがどこでマッピングされているかというと、
この URLパスパラメータのせっていです。
API Gatewayへのリクエストのパスに設定した値を、proxy_paramにセットしてあげる旨が設定されています。
(⭐)
結構これだけだと、わかりにくいと思うので図にするとこんな感じです。
たとえば、作成したAPIのURLが、
https://API GWのURL/stub_example/
だとして、リクエストしたとします。

そこに向かって、例えば
https://API GWのURL/stub_example/ex/API_A
のようなリクエストを投げると
(⭐)
API GatewayはS3からこの、「ex/API_A」をS3上のファイル名、(proxy_param)として解釈して
S3から持ってきます。
一旦、ここまでで、API Gatewayへのリクエストから、S3のファイルを持ってくることはできました。
では、この持ってきたファイルをどのようにマッピングするのかを見てみましょう。
(⭐)
S3に置くファイルは、こんな感じのJSONファイルです、
(⭐)
スタブが返すべき、ステータスコードと、
(⭐)
ヘッダ、
(⭐)
レスポンスボディの内容が記載されています。
(⭐)
このJSONファイルを、stub-exampleというS3バケットを作って、
(⭐)
「ex」ディレクトリ配下の「API_1.json」という名前でアップロードします。
S3の準備はこれで完了です。API Gatewayに戻って、クライアントへのレスポンスの設定をしていきます。
(⭐)
まずは、スタブがどんなレスポンスを返すのか定義していきましょう。
API Gatewayの「メソッドレスポンス」の設定を選択します。
(⭐)
ここでは、一旦HTTP ステータス200の時に、JSON形式のレスポンスを、Empty形式のレスポンスで返す旨を定義します。
ここは、後ほどの設定で書き換えていくので一旦スルーしてもらって構いません。
(⭐)
次に、S3のファイルの内容を、クライアント向けのレスポンスに変換していく設定を、この「統合レスポンス」で行います。
(⭐)
メソッドレスポンスのステータス200の設定を選択して、
マッピングテンプレート→ application/json を選択、
マッピングテンプレートを設定していきます。
(⭐)
マッピングテンプレートとはなんぞやー!
と思うかもしれませんが、これはリクエスト・レスポンスのヘッダやボディを
テンプレート言語を使ってできるものです。
Apache Velocity Template Languageという形で記述します。
(⭐)
たとえば、これを使うと、テンプレートを元に、
URLパラメータをリクエストボディに埋め込んだり、
リクエストパスの内容を、リクエストヘッダに設定したり、

S3のJSONをパースして、レスポンスボディに埋め込んだりすることができます。
ifや、forなども使用できます。
(⭐)
今回の場合だとこんな感じに記述できます。
S3から取得したJSONファイルがこのinputに格納されているので、JSONのルートからパースしてinputRootという変数にいれます。
JSONに記述されていた、レスポンスステータスを、API Gatewayがクライアントに返す、レスポンスステータスに設定。
同様にJSONに記述されたヘッダ情報を、API Gatewayがクライアントに返す、レスポンスヘッダに設定。
最後にJSONに記述されたbody情報を、API Gatewayがクライアントに返す、レスポンスボディに設定。
といった記述をします。
(⭐)
これで、一通りスタブがリクエストを受けて、S3からファイルを持ってきて、そのファイルを元にレスポンスをする。
という設定ができたので、スタブAPIをデプロイしてみます。
(⭐)
アクションから、APIのデプロイを選択・設定して次のようにデプロイすると・・・・
(⭐)
「ステージ」というタブの「stub」という項目に、このAPI GWのURLが表示されます。
では、実際にこのURLの「ex/API_1」というスタブにアクセスしてみましょう。
(⭐)
今回はcurlで、アクセスしてみます。
https://XXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/stub/ex/API_1
この部分が、API GatewayのURLですね、そして、この「ex/API_1」が、S3上のファイル名と対になることになります。

レスポンスを見てみると、レスポンスステータスや、ヘッダ、ボディが、JSONで指定した通り帰ってきていることがわかります。
指定した通り、レスポンスが帰ってきていていることが確認できたので、
(⭐)
完成しました。
(⭐)
まとめです。
Lambdaを使わずにスタブサーバを作ることができました。
jsonファイルを追加すればいいだけなので、誰でもスタブを追加しやすいと思います。
API GWはデフォルトでHTTPSなので、何か別途設定をしなくて良いのも楽ですね。
(⭐)
駆け足になってしまいましたが、いかがだったでしょうか。
便利なので、もしスタブを構築する機会があれば是非とも活用してみてください。
ご静聴ありがとうございました。

masa_charcoal (masachaco)

February 19, 2019
Tweet

More Decks by masa_charcoal (masachaco)

Other Decks in Technology

Transcript

  1. ࣗݾ঺հ HN:·ͪ͞Ό͜ • ۂͱ͔࡞ΔϓϩάϥϚ ܥ SIer • ϓϩάϥϛϯάݴޠ: Java /

    node.js • αʔόαΠυΞϓϦɺεϚʔτεϐʔΧʔΞϓϦͷ։ൃ • ٶͪΌΜͷসإۦಈ։ൃ • χίχίಈըͰϛΫ͞ΜୡͷۂΛެ։தʂ • Twitter • @masachaco • Web Site • http://lamnic.com/ • GitHub • https://github.com/masachaco • SoundCloud • https://soundcloud.com/masa_charcoal • niconico • https://www.nicovideo.jp/mylist/11613193
  2. Amazon API Gateway ։ൃαʔό ελϒϨεϙϯε1 ελϒϨεϙϯε2 ελϒϨεϙϯε3 Amazon S3 ׬੒Πϝʔδ

    "1*(BUFXBZ͕ ϦΫΤετͷύε΍ΫΤϦ΍ϔομΛݩʹɺϨε ϙϯε͢Δελϒͷ಺༰Λ4͔Βऔಘɻ ࠓճ͸؆୯ʹύε͚ͩͰ੾Γସ͑ΒΕΔΑ͏ʹ 
  3. Amazon API Gateway ։ൃαʔό ελϒϨεϙϯε1 ελϒϨεϙϯε2 ελϒϨεϙϯε3 Amazon S3 ׬੒Πϝʔδ

    4͔Βऔಘͨ͠ϑΝΠϧΛݩʹ Ϩεϙϯεϔομͱ ϨεϙϯεϘσΟΛ ࡞੒ͯ͠Ϩεϙϯε͢Δ
  4. ͜Μͳײ͡ͷURLͷ APIΛ࡞Γ·͢ https://(API GWͷURL)/Ϩεϙϯεఆ͕ٛهड़͞ΕͨϑΝΠϧ໊ ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹ! ྫɿ https://apigateway/ex/API_1 ɾ https://(API GWͷURL)/ex/API_1

    ʹΞΫηε͢Δͱɺ ɾ S3͔Βɺʮex/API_1.jsonʯͱ͍͏ϑΝΠϧΛ͖࣋ͬͯͯ ɾ ͦͷJSONϑΝΠϧʹॻ͔Ε͍ͯΔ಺༰Λݩʹ ɾ ΫϥΠΞϯτʹϨεϙϯεΛ͢Δʂ
  5. Amazon API Gateway ։ൃαʔό ex/API_A.json ex/API_B.json ex/API_C.json Amazon S3 ϦΫΤετΠϝʔδ

    )551.FUIPE(&5 ྫɿIUUQT 4ͷ63- TUVC@FYBNQMFFY"1*@"KTPO
  6. Apache VTL (Apache Velocity Template Language) Ͱهड़͢ΔϦΫΤετɾϨεϙϯεͷςϯϓϨʔτɻ ϚοϐϯάςϯϓϨʔτ Amazon API

    Gateway ։ൃαʔό Amazon S3 "1*(BUFXBZ͔Βଞ"84αʔϏε΁ͷ ϦΫΤετ΍ɺ "1*(BUFXBZ͔ΒɺΫϥΠΞϯτ΁ͷϨεϙϯεΛ ϚοϐϯάςϯϓϨʔτͰఆٛ͢Δ͜ͱ͕Ͱ͖Δɻ
  7. • S3͔Βड৴ͨ͠ϑΝΠϧͷ಺༰ΛݩʹϨεϙϯεϔομʹઃఆ ͢Δ • S3͔Βड৴ͨ͠಺༰ΛݩʹɺϨεϙϯεϘσΟΛઃఆ͢Δ • If ΍ for΋࢖͑Δ •

    etc.. (࣮͸S3΁ͷϦΫΤετʹ΋ϚοϐϯάςϯϓϨʔτ͸࢖͑Δ) ※ৄ͘͠͸ެࣜϦϑΝϨϯεΛࢀߟ ▪API Gateway ͷϚοϐϯάςϯϓϨʔτϦϑΝϨϯε
 https://docs.aws.amazon.com/ja_jp/apigateway/latest/ developerguide/api-gateway-mapping-template-reference.html ϚοϐϯάςϯϓϨʔτͰɺͰ͖Δ͜ͱ
  8. curlͰ࣮ߦ $ curl -X POST https://XXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/stub/ex/API_1 —verbose !Ϩεϙϯε < HTTP/2

    404 < date: Mon, 18 Feb 2019 10:06:15 GMT < content-type: application/json < content-length: 15 < x-amzn-requestid: XXXXXX-XXXXXXX-XXXXXXX-XXXXXXX < x-example-header-1: Header Value 1 < x-example-header-2: Header Value 2 < x-amz-apigw-id: XXXXXXXXXXXX < x-amzn-trace-id: XXXXXX-XXXXXXX-XXXXXXX-XXXXXXX < {"key1":"val1"} ࢀߟɿS3ʹஔ͍ͨjsonϑΝΠϧ
  9. ิ଍ • ΫϥΠΞϯτͷϦΫΤετΫΤϦ΍ɺϔομਓج͍ͮͯɺελϒͷϨε ϙϯεΛ੾Γସ͑Δʹ͸ɺผ్ϦΫΤετͷϚοϐϯάͷ௥Ճɾมߋ ͕ඞཁ
 • ը૾΍όΠφϦϑΝΠϧΛฦ͢ʹ͸΋͏Ұखؒඞཁ • (ΫϥΠΞϯτ͔ΒͷϦΫΤετϔομʹAcceptϔομͷ௥Ճɺ· ͨ͸ɺLambda͕ඞཁ)


    • खͷࠐΜͩϦΫΤετɾϨεϙϯεϚοϐϯάΛ͚ͤͨ͞Ε͹ɺ Lambdaͱ࿈ܞͯ͠ελϒϑΝΠϧͱϚοϐϯάͤͨ͞ํָ͕ͦ͏
 • ࣾ಺ͳͲVPC಺͚ͩʹެ։͍ͨ͠৔߹͸ɺϓϥΠϕʔτλΠϓͰAWI GWΛ࡞੒ͯ͠ɺVPCΤϯυϙΠϯτͷઃఆ͕ඞཁ
  10. curlͱϒϥ΢βͰ࣮ߦ $ curl -X POST https://XXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/stub/ex/API_2 —verbose < HTTP/2 201

    < date: Mon, 18 Feb 2019 10:11:40 GMT < content-type: application/xml < content-length: 26 < x-amzn-requestid: XXXXXXX-XXXXXXXXX-XXXXXXX-XXXXXXXX < x-amz-apigw-id: XXXXXXXX < x-amzn-trace-id: Root=XXXXXXXX-XXXXXX—XXXXXXXX < * Connection #0 to host XXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com left intact “<example>value</example>”