本投稿は、2015/3/23に行われたJAWS DAYS 2015 | クラウドへダイブ 〜 Dive Deep into the Cloud!のハンズオン企画のひとつ、「初心者ハンズオン(EC2)REST Webアプリ開発」で使用した資料を公開するものです。
メニュー
開発用サーバ作成
- AWSマネージメントコンソールにログイン
- 元にするAMI(マシンイメージ)を検索
- インスタンスタイプを選択
- インスタンス詳細設定
- ストレージ設定
- タグ設定
- セキュリティグループ設定
- 確認画面
- キーペア作成
- サーバ完成!
- ブラウザでアクセスしてみる
- SSHでアクセスしてみる
ソース取得、の前に前提知識を確認
- URL、Http Method
- CakePHPのController、Actionを含めまとめると
- HTTPレスポンスコード
GitHubからソース取得
- 鈴木商店用アカウントページを参照
- 開発用サーバにリポジトリをクローン
POSTMANで動作確認
- POSTMANの準備
- 全件取得してみる(GETメソッド)
- 1件取得してみる(GETメソッド:id付き)
- 追加してみる(POSTメソッド)
- 更新してみる(PUTメソッド)
- 削除してみる
今回作成する開発用サーバ
OSや基本的なソフトウェアがインストールされたマシンイメージをAWSではAMI(Amazon Machine Image)と呼びます。
今回は、弊社で作成したAMIを元にEC2インスタンスを作成します。
弊社がそのAMIを作成した手順については
AWS上で構築するRESTfulアプリ勉強会~Web開発ワークショップ~【第1回】の事前準備内容まとめ - Qiita
で公開しています。参考にしてください。
こうした方がいいよ、等あればコメントよろしくお願いします!
インストール済みプロダクト
予め下記プロダクトをインストール済みです。
今回の手順で開発環境を作成すればすぐに使用可能となります。
プロダクト | バージョン |
---|---|
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です。
- 当資料では、Macの標準ターミナルと、Windows上のputtyでの実行例を併記しています。
開発用サーバ作成
では、鈴木商店にて事前準備済みのAMIから以下の手順でEC2インスタンスを作成します。
1. AWSマネージメントコンソールにログイン
2. 元にするAMI(マシンイメージ)を検索
下記手順で当該のAMIを表示させます。
下記AMIsの部分をクリックします。
次に、下記の通り操作します。
リージョンがTokyoになっていることを確認。
画面上部右端にリージョンの表示があります(Tokyoになっている場合)。
Tokyoになっていない場合、下図のようにTokyoリージョンを選択してください。
AMIを検索します。
- フィルタを[Public Images]に設定
- AMI ID
ami-fb07f0fb
で検索(JawsDays2015_handson_suzukishouten
で検索しても出てくるはずです)。
以降、作成するインスタンスの設定をしていきます。
3.インスタンスタイプを選択
t2.microを選択して[Next]。
4.インスタンス詳細設定
基本はデフォルトで[Next]クリックでOKです。。
Protect against accidental termination
にチェックを入れていますが、ここにチェックしておくと、インスタンス完成後に間違っていterminate(破棄!)をクリックしてしまった時に救われます。(このチェックを外してからでないとterminateできなくなるので安全です)
ですので、チェックを入れることをおすすめします。
5.ストレージ設定
ストレージを追加します。デフォルトでOKです。[Next]クリック。
6.タグ設定
好きな名前をつけて[Next]クリック。
ここではjawsdays_2015
と命名。
7.セキュリティグループ設定
アクセスを許可するプロトコルやポートを設定します。
下記の通り設定し、[Review And Launch]をクリック。
- Create a new security groupを選択
- Security group name 好きな名前(スクリーンショットでは、
web-public
としています。) - Description 好きな説明文(スクリーンショットでは、
jawsdays_2015
としています。) - SSH Anywhere
- Http Anywhere
ssh, httpは今回必須です。標準のポートで設定します。
ソースIPアドレスは、スクリーンショットではAnywhere
(どこからでもアクセス可能)にしています。(セキュリティの警告が出ますが、今回はこれでOK)。
8.確認画面
これまで設定した内容のサマリ。問題なければ[Launch]クリック。
(警告が出てますが、上記と同様なのでOK)
9.キーペア作成
SSHアクセスに必要なキーペアを作成します。
Create a new key pair
を選択しKey pair name
にキーの名前を入力します。
既に作成済みのキーがあり、それを使用するなら、Choose an existing key pair
を選択し、さらにSelect a key pair
欄で鍵を選択します。。
ここでは、jawsdays_2015
と命名。
[Download Key Pair]をクリックすると秘密鍵の書かれたテキストがダウンロードされるので、拡張子を.pem
にして保存しておきます。
このあたり、MacとWindowsでは少し違いますので説明します。
Macの場合
MacやLinuxでは、sshの鍵は一般的にユーザのホームディレクトリの下の.ssh
ディレクトリに保存します。(~/.ssh
)。
今回はそれに倣います。
コピーした.pemファイルは読み取り専用にしておきます(chmod 600
)。
通常、.
付きのファイルやディレクトリはFinderからは見えませんので、ターミナルで作業します。
以下、Mac上での作業です。
- sshディレクトリ作成(ない場合)
cd ~/
でユーザのホームディレクトリに移動、mkdir
でディレクトリ作成。
cd ~/
mkdir .ssh
- ダウンロードした鍵ファイルをコピー
鍵のファイル名はjawsdays_2015.pem
としました。
cp ダウンロードした鍵ファイルのフルパス ~/.ssh/jawsdays_2015.pem
chmod 600 ~/.ssh/jawsdays_2015.pem
Windowsの場合
今回はputtyを使用した接続を行います。
puttyの場合、ダウンロードした鍵をputty用の形式に変換し、変換後の鍵を使用する必要があるので、いったん好きなところに適当な名前で保存してください。(鍵の変換方法は後述)
以降のスクリーンショットでは、デスクトップにjawsdays_2015.pem
で保存したイメージになっています。
以降の説明でも秘密鍵のファイル名は"jawsdays_2015.pem"で表記します。
これで鍵の準備はOKです。
[Launch Instances]がクリック出来るようになっていますので、クリックします。
10.サーバ完成!
下記画面が出ればOKです![View Instances]をクリックします。
右の方にスクロールすると、[Public IP]が表示されています。
この後、ブラウザからのアクセス、SSHでのアクセスは全てこのIPアドレスに対して行います。
忘れたらこの画面で確認して下さい。
以降の説明では、このアドレス部分は"[Public IP]"と表記します。
11. ブラウザでアクセスしてみる
http://[Public IP]/
にアクセスすると、apacheのデフォルトルートドキュメントが表示されます。
12. SSHでアクセスしてみる
Mac, Windowsでやりかたが違いますので、それぞれ記載します。
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用に変換
デフォルトでは、拡張子.pem
は表示されないので、[All Files]を選択し、ダウンロードした鍵ファイルを選択し、開きます。
ファイル名を入力して保存(拡張子は、.ppk
にします)。
これで鍵の変換は終了。
今回はデスクトップの保存していますが、本来はもう少し深いところにおいてください。
sshで接続
Categoryから[Session]を選択し、下記の通り入力します。
- HostName
ec2-user@[Public IP]
- Port
22
- Connection type
SSH
Categoryから[Connection]>[SSH]>[Auth]と選択し、[Browse]ボタンをクリックして作成した.ppk
のファイルを選択します。ここまででパラメータ設定は終わりです。続いてこの設定を保存します。
再び[Session]を選択し、[Saved Sessions]欄に名前を入力し、[Save]ボタンをクリックすると、設定した接続設定に名前をつけて保存することができます。
[Open]をクリックすると接続します。
ソース取得、の前に前提知識を確認
鈴木商店の主催する勉強会でも使用している、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番台 : サーバエラー
となります。
参考 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
このリポジトリを自分の開発用サーバにCloneします。
ec2-user
ユーザでsshログインし、/var/www/jawsdays_2015
に移動してから下記のようにgit clone
コマンドを叩きます。
コマンドは、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の準備
POSTMAN、または同様の別ツールをインストール済みの方はここはとばしてください。
POSTMANはchromeブラウザの拡張機能です。
下記からインストールします。
インストールしたら、次回起動のためにブックマークしておいてください。
Postman - REST Client - Chrome ウェブストア
では、下記に全件取得、1件取得、追加、更新、削除する際のPOSTMANに設定するパラメータを記載します。
試しみましょう!
全件取得してみる(GETメソッド)
- URL:
http://[Public IP]/todo_lists.json
- メソッド:GET
1件取得してみる(GETメソッド:id付き)
- URL:
http://[Public IP]/todo_lists/1.json
- "1"のところは、更新したいデータのIDを指定する
- メソッド:GET
追加してみる(POSTメソッド)
- URL:
http://[Public IP]/todo_lists.json
- メソッド:POST
- HTTPヘッダ: Content-Type : application/json
- データ: ROW, JSON
{
"todo": "鈴木商店に入社する",
"status": "0"
}
更新してみる(PUTメソッド)
- URL:
http://[Public IP]/todo_lists/1.json
- "1"のところは、更新したいデータのIDを指定する
- メソッド:PUT
- HTTPヘッダ: Content-Type : application/json
- データ: ROW, JSON
{
"todo": "鈴木商店の面接を受ける",
"status": "0"
}
削除してみる
- URL:
http://[Public IP]/todo_lists/2.json
- "2"のところは、削除したいデータのIDを指定する
- メソッド:DELETE
以上です!
※追記 Postmanでの、"form-data"と"form-datax-www-form-urlencoded"の違いについて
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
です。
お疲れ様でした!
うまく行きましたでしょうか?
勉強会もやってますので、よかったら来てくださいね!