Edited at

JAWS DAYS 2015 ハンズオン 〜REST Webアプリ開発〜

More than 3 years have passed since last update.

本投稿は、2015/3/23に行われたJAWS DAYS 2015 | クラウドへダイブ 〜 Dive Deep into the Cloud!のハンズオン企画のひとつ、「初心者ハンズオン(EC2)REST Webアプリ開発」で使用した資料を公開するものです。


メニュー

開発用サーバ作成


  1. AWSマネージメントコンソールにログイン

  2. 元にするAMI(マシンイメージ)を検索

  3. インスタンスタイプを選択

  4. インスタンス詳細設定

  5. ストレージ設定

  6. タグ設定

  7. セキュリティグループ設定

  8. 確認画面

  9. キーペア作成

  10. サーバ完成!

  11. ブラウザでアクセスしてみる

  12. SSHでアクセスしてみる

ソース取得、の前に前提知識を確認


  1. URL、Http Method

  2. CakePHPのController、Actionを含めまとめると

  3. HTTPレスポンスコード

GitHubからソース取得


  1. 鈴木商店用アカウントページを参照

  2. 開発用サーバにリポジトリをクローン

POSTMANで動作確認


  1. POSTMANの準備

  2. 全件取得してみる(GETメソッド)

  3. 1件取得してみる(GETメソッド:id付き)

  4. 追加してみる(POSTメソッド)

  5. 更新してみる(PUTメソッド)

  6. 削除してみる


今回作成する開発用サーバ

OSや基本的なソフトウェアがインストールされたマシンイメージをAWSではAMI(Amazon Machine Image)と呼びます。

今回は、弊社で作成したAMIを元にEC2インスタンスを作成します。

 :warning:弊社がそのAMIを作成した手順については

AWS上で構築するRESTfulアプリ勉強会~Web開発ワークショップ~【第1回】の事前準備内容まとめ - Qiita

で公開しています。参考にしてください。

 :warning:こうした方がいいよ、等あればコメントよろしくお願いします!


インストール済みプロダクト

予め下記プロダクトをインストール済みです。

今回の手順で開発環境を作成すればすぐに使用可能となります。

プロダクト
バージョン

apache
2.4.10-1.59

php
5.5.20-2.94

mysql
5.6.14-3

phpMyAdmin
4.0.10.7-1

git
2.1.0

xdebug
2.2.3-1


今回使用するツールなど、必要なもの


  • awsアカウント


    • 必須です!EC2インスタンスが作成できることを事前に確認しておくとベターです。



以下、別のツールでも代替できますが、説明は下記ツールをベースに行います。


  • chromeブラウザ


  • postman


    • 作成したAPIのテストツールchromeブラウザの拡張機能です。



    • 似たようなツールはたくさんありますので、愛用のものがあればそちらで結構です。




  • ターミナルソフトウェア


    • Mac, Linuxの方は標準のターミナルでよいです。

    • Windowsの方は、別途ターミナルソフトウェアをご準備ください。


      • 当資料では、Macの標準ターミナルと、Windows上のputtyでの実行例を併記しています。


        • 事前にPuTTY Download Pageよりインストールしておいてください(インストーラでインストールしたくない場合はputty.zipをダウンロードしてすきなところに解凍すればOKです。








開発用サーバ作成

では、鈴木商店にて事前準備済みのAMIから以下の手順でEC2インスタンスを作成します。


1. AWSマネージメントコンソールにログイン

ログイン後、下図のEC2をクリックします。

aws_menu.png


2. 元にするAMI(マシンイメージ)を検索

下記手順で当該のAMIを表示させます。

下記AMIsの部分をクリックします。

aws_sidemenu.png

次に、下記の通り操作します。

リージョンがTokyoになっていることを確認。

画面上部右端にリージョンの表示があります(Tokyoになっている場合)。

ami_region.png

Tokyoになっていない場合、下図のようにTokyoリージョンを選択してください。

ami_region_select.png

AMIを検索します。


  • フィルタを[Public Images]に設定

  • AMI ID ami-fb07f0fbで検索(JawsDays2015_handson_suzukishoutenで検索しても出てくるはずです)。

ami_search_result.png

見つかったら、選択して[Launch]ボタンをクリック。

ami_launch.png

以降、作成するインスタンスの設定をしていきます。


3.インスタンスタイプを選択

t2.microを選択して[Next]。

ec2_step2.png


4.インスタンス詳細設定

基本はデフォルトで[Next]クリックでOKです。。

Protect against accidental terminationにチェックを入れていますが、ここにチェックしておくと、インスタンス完成後に間違っていterminate(破棄!)をクリックしてしまった時に救われます。(このチェックを外してからでないとterminateできなくなるので安全です)

ですので、チェックを入れることをおすすめします。

ec2_step3.png


5.ストレージ設定

ストレージを追加します。デフォルトでOKです。[Next]クリック。

ec2_step4.png


6.タグ設定

好きな名前をつけて[Next]クリック。

:warning:ここではjawsdays_2015と命名。

ec2_step5.png


7.セキュリティグループ設定

アクセスを許可するプロトコルやポートを設定します。

下記の通り設定し、[Review And Launch]をクリック。


  • Create a new security groupを選択

  • Security group name 好きな名前(スクリーンショットでは、web-publicとしています。)

  • Description 好きな説明文(スクリーンショットでは、jawsdays_2015としています。)

  • SSH Anywhere:warning:

  • Http Anywhere:warning:

:warning:ssh, httpは今回必須です。標準のポートで設定します。

ソースIPアドレスは、スクリーンショットではAnywhere(どこからでもアクセス可能)にしています。(セキュリティの警告が出ますが、今回はこれでOK)。

ec2_step6.png


8.確認画面

これまで設定した内容のサマリ。問題なければ[Launch]クリック。

(警告が出てますが、上記と同様なのでOK)

ec2_step7.png


9.キーペア作成

SSHアクセスに必要なキーペアを作成します。

Create a new key pairを選択しKey pair nameにキーの名前を入力します。

:warning:既に作成済みのキーがあり、それを使用するなら、Choose an existing key pairを選択し、さらにSelect a key pair欄で鍵を選択します。。

:warning:ここでは、jawsdays_2015と命名。

ec2_step7_dialog1.png

[Download Key Pair]をクリックすると秘密鍵の書かれたテキストがダウンロードされるので、拡張子を.pemにして保存しておきます。

このあたり、MacとWindowsでは少し違いますので説明します。


Macの場合

MacやLinuxでは、sshの鍵は一般的にユーザのホームディレクトリの下の.sshディレクトリに保存します。(~/.ssh)。

今回はそれに倣います。

コピーした.pemファイルは読み取り専用にしておきます(chmod 600)。

通常、.付きのファイルやディレクトリはFinderからは見えませんので、ターミナルで作業します。

以下、Mac上での作業です。


  • sshディレクトリ作成(ない場合)

cd ~/でユーザのホームディレクトリに移動、mkdirでディレクトリ作成。

cd ~/

mkdir .ssh


  • ダウンロードした鍵ファイルをコピー

:warning:鍵のファイル名はjawsdays_2015.pemとしました。

cp ダウンロードした鍵ファイルのフルパス ~/.ssh/jawsdays_2015.pem

chmod 600 ~/.ssh/jawsdays_2015.pem


Windowsの場合

今回はputtyを使用した接続を行います。

puttyの場合、ダウンロードした鍵をputty用の形式に変換し、変換後の鍵を使用する必要があるので、いったん好きなところに適当な名前で保存してください。(鍵の変換方法は後述)

:warning:以降のスクリーンショットでは、デスクトップにjawsdays_2015.pemで保存したイメージになっています。

:warning:以降の説明でも秘密鍵のファイル名は"jawsdays_2015.pem"で表記します。

これで鍵の準備はOKです。

[Launch Instances]がクリック出来るようになっていますので、クリックします。

ec2_step7_dialog2.png


10.サーバ完成!

下記画面が出ればOKです![View Instances]をクリックします。

ec2_finish.png

インスタンス一覧に今作成したインスタンスが表示されました!

ec2_view.png

右の方にスクロールすると、[Public IP]が表示されています。

この後、ブラウザからのアクセス、SSHでのアクセスは全てこのIPアドレスに対して行います。

忘れたらこの画面で確認して下さい。

:warning:以降の説明では、このアドレス部分は"[Public IP]"と表記します。

publicip.png


11. ブラウザでアクセスしてみる

http://[Public IP]/

にアクセスすると、apacheのデフォルトルートドキュメントが表示されます。

web_test.png


12. SSHでアクセスしてみる

Mac, Windowsでやりかたが違いますので、それぞれ記載します。

:warning:Linuxを使用している方はほぼMacと同じはずですので割愛します。


Macの場合

標準のターミナルを起動します。

ここからはターミナル上で操作します。

sshを実行し、ec2-userというユーザでログインします。

コマンドラインは下記の通り、ssh -i 秘密鍵のパス ユーザ名@接続先ホスト名(IPアドレス)です。

ssh -i ~/.ssh/jawsdays_2015.pem ec2-user@[Public IP]

うまく行けばこんな感じで表示されます。


__| __|_ )
_| ( / Amazon Linux AMI
___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2014.09-release-notes/
25 package(s) needed for security, out of 36 available
Run "sudo yum update" to apply all updates.```


Windowsの場合

puttyでの例です。


ダウンロードした鍵をputty用に変換

PUTTYGEN.EXEを起動します。

puttygen.png

[Load]をクリックします。

puttygen_1.png

デフォルトでは、拡張子.pemは表示されないので、[All Files]を選択し、ダウンロードした鍵ファイルを選択し、開きます。

puttygen_2.png

これでOK。

puttygen_3.png

[Save private key]をクリック。

puttygen_4.png

パスフレーズがないという警告が出ますが構わず[はい]。

puttygen_5.png

ファイル名を入力して保存(拡張子は、.ppkにします)。

これで鍵の変換は終了。

:warning:今回はデスクトップの保存していますが、本来はもう少し深いところにおいてください。

puttygen_6.png


sshで接続

PUTTY.EXEを起動します。

putty.png

Categoryから[Session]を選択し、下記の通り入力します。


  • HostName ec2-user@[Public IP]

  • Port 22

  • Connection type SSH

putty_1.png

Categoryから[Connection]>[SSH]>[Auth]と選択し、[Browse]ボタンをクリックして作成した.ppkのファイルを選択します。ここまででパラメータ設定は終わりです。続いてこの設定を保存します。

putty_2.png

再び[Session]を選択し、[Saved Sessions]欄に名前を入力し、[Save]ボタンをクリックすると、設定した接続設定に名前をつけて保存することができます。

[Open]をクリックすると接続します。

putty_3.png

こんな画面がでればOK!

putty_4.png


ソース取得、の前に前提知識を確認

鈴木商店の主催する勉強会でも使用している、TODOリストアプリケーションのソースをGitHubから取得して動作させてみますが、そのまえに、URL、CakePHPのController、 Actionの関係について確認しておきます(重要)。


URL、Http Method

RESTアプリケーションでは、リソースに対してユニークなURIを割付け、それに対してアクセスします。

そのリソースに対してどのような処理を行うかをHttp Methodで指定します。

(例)

URL


  • todoリストの一覧


    • /todo_lists.json



  • todoリストのidが'1'の1件


    • /todo_lists/1.json



Http Method

Http Method
処理

GET
取得する

POST
追加する

PUT
更新する

DELETE
削除する


CakePHPのController、Actionを含めまとめると

下表の通り、URL、HttpMethod、行う処理、CakePHPのControllerとActionが対応します。

下に、今回作成するソースを載せていますが、この表の通り作成されています。

URL
Http Method
処理
Controller
Action

/todo_lists.json
GET
TODOリスト一覧を取得する
TodoListsController
index

/todo_lists/1.json
GET
TODOリストのidが'1'の1件を取得する
TodoListsController
view

/todo_lists.json
POST
TODOリストに1件追加する
TodoListsController
add

/todo_lists/1.json
PUT
TODOリストのidが'1'の1件を更新する
TodoListsController
edit

/todo_lists/1.json
DELETE
TODOリストのidが'1'の1件を削除する
TodoListsController
delete


HTTPレスポンスコード

APIの処理結果は、HTTPレスポンスコードで返すようにするのが基本です。

大雑把に言うと、


  • 200番台 : 正常終了

  • 300番台 : リダイレクト

  • 400番台 : クライアントエラー

  • 500番台 : サーバエラー

となります。

:warning:参考 HTTPステータスコード - Wikipedia

例)

リソースの追加を行い、成功した場合(POST)は、"201 Created"と返す。

では、ソースを取得します!


GitHubからソース取得


鈴木商店用GitHubアカウントページを参照

下記URLにアクセスしてください。鈴木商店の主催する勉強会でも使用しているGitHubリポジトリです。ここに今回使用するソースがあります。

https://github.com/suzukishouten-study/jawsdays_2015


開発用サーバにリポジトリをクローン

赤枠の部分にクローン元のURLがあります。今回はhttpsでのアクセスとしますので、https〜で始まるURLを使用します。

クローン元URL: https://github.com/suzukishouten-study/jawsdays_2015.git

github_suzukishouten.png

このリポジトリを自分の開発用サーバにCloneします。

ec2-userユーザでsshログインし、/var/www/jawsdays_2015に移動してから下記のようにgit cloneコマンドを叩きます。

:warning: コマンドは、git clone https://github.com/suzukishouten-study/jawsdays_2015.git .です。

最後の "." の打ち忘れに注意!忘れると、サブディレクトリjawsdays_2015が作成され、その中にCloneされますので、ディレクトリ階層がひとつ深くなってしまいます。

cd /var/www/jawsdays_2015

git clone https://github.com/suzukishouten-study/jawsdays_2015.git .
Cloning into '.'...
remote: Counting objects: 1459, done.
remote: Compressing objects: 100% (810/810), done.
remote: Total 1459 (delta 440), reused 1451 (delta 440), pack-reused 0
Receiving objects: 100% (1459/1459), 1.73 MiB | 950.00 KiB/s, done.
Resolving deltas: 100% (440/440), done.
Checking connectivity... done.

これで、/var/www/jawsdays_2015にTODOリストアプリケーションのソースがcloneされました。


POSTMANで動作確認


POSTMANの準備

:warning:POSTMAN、または同様の別ツールをインストール済みの方はここはとばしてください。

POSTMANはchromeブラウザの拡張機能です。

下記からインストールします。

:warning:インストールしたら、次回起動のためにブックマークしておいてください。

Postman - REST Client - Chrome ウェブストア

postman.png

では、下記に全件取得、1件取得、追加、更新、削除する際のPOSTMANに設定するパラメータを記載します。

試しみましょう!


全件取得してみる(GETメソッド)


  • URL:http://[Public IP]/todo_lists.json

  • メソッド:GET

[Send]をクリック!

postman1.png


1件取得してみる(GETメソッド:id付き)


  • URL:http://[Public IP]/todo_lists/1.json


    • "1"のところは、更新したいデータのIDを指定する



  • メソッド:GET

[Send]をクリック!

postman2.png


追加してみる(POSTメソッド)


  • URL:http://[Public IP]/todo_lists.json

  • メソッド:POST

  • HTTPヘッダ: Content-Type : application/json

  • データ: ROW, JSON

{

"todo": "鈴木商店に入社する",
"status": "0"
}

[Send]をクリック!

postman3.png


更新してみる(PUTメソッド)


  • URL:http://[Public IP]/todo_lists/1.json


    • "1"のところは、更新したいデータのIDを指定する



  • メソッド:PUT

  • HTTPヘッダ: Content-Type : application/json

  • データ: ROW, JSON

{

"todo": "鈴木商店の面接を受ける",
"status": "0"
}

[Send]をクリック!

postman4.png


削除してみる


  • URL:http://[Public IP]/todo_lists/2.json


    • "2"のところは、削除したいデータのIDを指定する



  • メソッド:DELETE

[Send]をクリック!

postman5.png

以上です!


※追記 Postmanでの、"form-data"と"form-datax-www-form-urlencoded"の違いについて

:warning:pugiemonn様よりコメント頂いた件を本文に転記しておきます。

PUTメソッドで送信する場合の動作について。


(1) form-dataの場合

"Content-type"が"multipart/form-data"に設定され、送信データが複数パートに分割される形式で送られます。

通常はファイルアップロード等を実行する際に指定する形式です。

下記の様になります。(id=1, status=0, todo=あいうえおとした場合)



------WebKitFormBoundaryBKsP47JxDdxYnfHW

Content-Disposition: form-data; name="id"
1
------WebKitFormBoundaryBKsP47JxDdxYnfHW
Content-Disposition: form-data; name="status"
0
------WebKitFormBoundaryBKsP47JxDdxYnfHW
Content-Disposition: form-data; name="todo"
あいうえお
------WebKitFormBoundaryBKsP47JxDdxYnfHW--

この形式だと、今回のTODOリストサーバ側プログラムで正しく送信データが取得できません。


(2) "x-www-form-urlencoded"の場合

"Content-type"が"application/x-www-form-urlencoded"に設定され、送信データは"名前1=値1&名前2=値2..."の形式で送られます。また、送信データはURLエンコードされます。

いわゆるフツーのformのpostで使用する形式です。



id=11&status=0&todo=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A



(3) raw + Content-type=application/json(この記事で紹介している方式)

明示的ににContent-typeを指定してあげると、送信データは"{名前: 値1, 名前2: 値2, ...}と、書いた通り送られ、サーバはJson形式であるものとして認識します。

今回のRestアプリケーションでは、送受信とも全てJSONを想定しているので、この方法がベストです。



{id: 1, todo: "あいうえお", status: "0"}


(2)でもちゃんと動くのは、CakePHPのRequestHandlerがよろしくやってくれて、アプリケーションからは(2)でも(3)でも、単なる配列(連想配列)として取得できるようになっているからですね。

参考URL リクエストハンドリング — CakePHP Cookbook 2.x ドキュメント


phpMyAdminについて

http://[Public IP]/phpMyAdmin/

にアクセスすると起動できます。

user : root

password : jawsdays_2015

でOKです。パスワードは変えておきましょう!

今回使用しているテーブルは、jawsdays_2015/todo_listsです。


お疲れ様でした!

うまく行きましたでしょうか?

勉強会もやってますので、よかったら来てくださいね!