#勉強会-開発パート - 第1回当日手順
本投稿は、2015/1/23に行われたAWS上で構築するRESTfulアプリ勉強会~Web開発ワークショップ~【第1回】で使用した資料を再構成したものです。
※参加された方へ。
資料に幾つか不備、不十分な点がありましたが、修正したり詳しくしたりしています。当日これぐらい書けていればもう少しスムーズに進んだと思いますが...。スミマセンでした。
この資料を元にもう一回やってみてフィードバックもらえると助かります。
なお、第2回はこの内容を終えていることが前提になりますのでよろしくお願いします。
メニュー
開発用サーバ作成
- AWSマネージメントコンソールにログイン
- 元にするAMI(マシンイメージ)を検索
- インスタンスタイプを選択
- インスタンス詳細設定
- ストレージ設定
- タグ設定
- セキュリティグループ設定
- 確認画面
- キーペア作成
- サーバ完成!
- ブラウザでアクセスしてみる
- SSHでアクセスしてみる
GitHubからソース取得
- fork
- 開発用サーバにリポジトリをクローン
シンプルTODOアプリ作成
- POSTMANの準備
- プログラミング
- そのまえに、urlとController.Actionの関係について(重要)
- URL
- 行う処理
- まとめると
- HTTPレスポンスコードについて
- ソース修正手順
- 開発用ブランチ作成
- ソースを修正する。
- POSTMANで動作確認
- phpMyAdminでデータ確認
- git初期設定
- git add, commit
- git push
- ソース修正箇所
- 修正ファイルのdiff
- 追加ファイル
今回作成する開発用サーバ
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インスタンスが作成できることを確認しておくとベターです。
- GitHubアカウント
- 今回はログインさえできれば準備OKです。
- chromeブラウザ
- 説明はchromeブラウザをベースにしています。
- 今後もchromeブラウザをベースに資料、説明を行います。
- postman
-
作成したAPIのテストツールchromeブラウザの拡張機能です。
-
似たようなツールはたくさんありますので、愛用のものがあれば別のそれでもいいですが、資料、説明はPOSTMANベースです。
-
- sshコマンドが叩ける環境
- Macの方は標準のターミナルから実行できるので事前準備は特に必要ないです。
- Windowsの方は、別途ターミナルソフトウェアをご準備ください。
- 当資料では、puttyを例にして説明しています。事前にPuTTY Download Pageよりインストールしておいてください(インストーラでインストールしたくない場合はputty.zipをダウンロードしてすきなところに解凍すればOKです。putty以外を愛用していて、linuxサーバへのsshログインが問題なく行える場合は好きなターミナルソフトウェアをご使用ください。
- Vimまたはemacsの基本操作が出来るようになっておく。
- サーバにログインして作業することになりますので、エディタはサーバ上のVimまたはemacsを使用します。基本操作は覚えておいてください(ローカルで編集してターミナル上でコピペ出来るレベルで最低限はOKです!)。
- サーバ上のファイルをローカルPC上のエディタから編集する他の方法もそのうちまとめます...
開発用サーバ作成
では、事前準備済みのAMIから以下の手順でEC2インスタンスを作成します。
1. AWSマネージメントコンソールにログイン
ログイン後、下図のEC2をクリックします。
2. 元にするAMI(マシンイメージ)を検索
下記手順で当該のAMIを表示させます。
下記AMIsの部分をクリックします。
次に、下記の通り操作します。
リージョンがTokyoになっていることを確認。
画面上部右端にリージョンの表示があります(Tokyoになっている場合)。
Tokyoになっていない場合、下図のようにTokyoリージョンを選択してください。
AMIを検索します。
- フィルタを[Public Images]に設定
- AMI ID
ami-644f5165
で検索(suzukishouten
で検索しても出てくるはずです)。
以降、作成するインスタンスの設定をしていきます。
3.インスタンスタイプを選択
t2.microを選択して[Next]。
4.インスタンス詳細設定
基本はデフォルトで[Next]クリックでOKです。。
Protect against accidental termination
にチェックを入れていますが、ここにチェックしておくと、インスタンス完成後に間違っていterminate(破棄!)をクリックしてしまった時に救われます。(このチェックを外しておかないとterminateできない)
ですので、チェックを入れることをおすすめします。
5.ストレージ設定
ストレージを追加します。デフォルトでOK。[Next]クリック。
6.タグ設定
好きな名前をつけて[Next]クリック。
※スクリーンショットではstudy_01
と命名。
7.セキュリティグループ設定
アクセスを許可するプロトコルやポートを設定します。
下記の通り設定し、[Review And Launch]をクリック。
- Create a new security groupを選択
- Security group name 好きな名前
- Description 好きな説明文
- 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
欄で鍵を選択します。。
[Download Key Pair]をクリックすると秘密鍵の書かれたテキストがダウンロードされるので、拡張子を.pem
にして保存しておきます。
このあたり、MacとWindowsでは少し違いますので説明します。
Macの場合
MacやLinuxでは、sshの鍵は一般的にユーザのホームディレクトリの下の.ssh
ディレクトリに保存します。(~/.ssh
)。
今回はそれに習います。
コピーした.pemファイルは読み取り専用にしておきます(chmod 600
)。
通常、.
付きのファイルやディレクトリはFinderからは見えませんので、ターミナルで作業します。
以下、Mac上での作業です。
- sshディレクトリ作成(ない場合)
cd ~/
でユーザのホームディレクトリに移動、mkdir
でディレクトリ作成。
cd ~/
mkdir .ssh
- ダウンロードした鍵ファイルをコピー
※鍵のファイル名はstudy_01.pem
としました。
cp ダウンロードした鍵ファイルのフルパス ~/.ssh/study_01.pem
chmod 600 ~/.ssh/study_01.pem
Windowsの場合
今回はputtyを使用した接続を行います。
puttyの場合、ダウンロードした鍵をputty用の形式に変換し、変換後の鍵を使用する必要があるので、いったん好きなところに適当な名前で保存してください。(鍵の変換方法は後述)
※以降のスクリーンショットでは、デスクトップにstudy_01.pem
で保存したイメージになっています。
これで鍵の準備はOKです。
[Launch Instances]がクリック出来るようになっていますので、クリックします。
10.サーバ完成!
下記画面が出ればOKです![View Instances]をクリックします。
インスタンス一覧に今作成したインスタンスが表示されました!
右の方にスクロールすると、[Public IP]が表示されています。
この後、ブラウザからのアクセス、SSHでのアクセスは全てこのIPアドレスに対して行います。
忘れたらこの画面で確認して下さい。
11. ブラウザでアクセスしてみる
http://(public ip)/
にアクセスすると、apacheのデフォルトルートドキュメントが表示されます。
12. SSHでアクセスしてみる
Mac, Windowsでやりかたが違いますので、それぞれ記載します。
※Linuxを使用している方はほぼMacと同じはずですので割愛します。
Macの場合
標準のターミナルを起動します。
/アプリケーション/ユーティリティ/ターミナル
を起動します。
ここからはターミナル上で操作します。
sshを実行し、ec2-user
というユーザでログインします。
コマンドラインは下記の通り、ssh -i 秘密鍵のパス ユーザ名@接続先ホスト名(IPアドレス)
です。
ssh -i ~/.ssh/ダウンロードした.pem ec2-user@GlobalIP
うまく行けばこんな感じで表示されます。
__| __|_ )
_| ( / 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を使用します。
手順は、ここに詳しく書かれていますので、その通りでOKですが、実際にやってみたスクリーンショットとともに載せておきます。
ダウンロードした鍵をputty用に変換します。
PUTTYGEN.EXEを起動します。
[Load]をクリックします。
デフォルトでは、拡張子.pem
は表示されないので、[All Files]を選択し、ダウンロードした鍵ファイルを選択し、開きます。
これでOK。
[Save private key]をクリック。
パスフレーズがないという警告が出ますが構わず[はい]。
ファイル名を入力して保存(拡張子は、.ppk
にします)。
これで鍵の変換は終了。
※今回はデスクトップの保存していますが、本来はもう少し深いところにおいてください。
sshで接続します。
PUTTY.EXEを起動します。
Categoryから[Session]を選択し、下記の通り入力します。
- HostName
ec2-user@GlobalIP
- Port
22
- Connection type
SSH
Categoryから[Connection]>[SSH]>[Auth]と選択し、[Browse]ボタンをクリックして作成した.ppk
のファイルを選択します。ここまででパラメータ設定は終わりです。続いてこの設定を保存します。
再び[Session]を選択し、[Saved Sessions]欄に名前を入力し、[Save]ボタンをクリックすると、設定した接続設定に名前をつけて保存することができます。
[Open]をクリックすると接続します。
こんな画面がでればOK!
study
ユーザを使用する。
次に、作業用として作成したstudy
ユーザがすでにいますので、そちらで接続します。
今後、作業はec2-userではなく、studyユーザを使用しましょう。
ただし、studyユーザで使用する鍵がありません。
先ほどダウンロードした秘密鍵に対する公開鍵(ec2-user用です)が、/home/ec2-user/.ssh/authorized_keys
にあるので、それをstudyユーザ用としても使用するようにコピーしてしまうと楽です。以下、手順です。
まず、上記手順でec2-user
でログイン後、管理者(root)に成ります。
sudo -i
※この時はパスワード不要です。
続いて、ec2-userの公開鍵をstudyユーザも使用するようにコピーします。
cp /home/ec2-user/.ssh/authorized_keys /home/study/.ssh/
次に、コピーした鍵のオーナを変更します。
chown study:study /home/study/.ssh/authorized_keys
表示してみます。下記のような表示になっていればOKです。
ll /home/study/.ssh/authorized_keys
合計 4
-rw------- 1 study study 1207 1月 26 12:09 authorized_keys
これでstudyユーザでログイン出来るようになりました。
ec2-user
からいったんログアウトし(logout
コマンドまたはキーボードでCTRL+d
)、study
ユーザでログインしてみます。
ssh -i ~/.ssh/ダウンロードした.pem study@GlobalIP
study
ユーザにはパスワードが設定されていますので、管理者になるには、パスワード入力が必要です。
※パスワードはユーザ名と同じstudy
が設定されています。
sudo -i
password for study:
と、パスワード入力を求めるプロンプトが出ますので、study
を入力します。
以上でSSH接続はOKです!
セキュリティ的には、studyユーザのパスワードを変更し、ec2-userを削除することをおすすめします。
※今回は必須ではないですが、やり方を載せておきます。
パスワードを変更するには、studyユーザでログイン後、passwd
コマンドを叩きます。以下実行例。
[study@ip-172-31-8-2 ~]$ passwd
ユーザー study のパスワードを変更。
study 用にパスワードを変更中
現在の UNIX パスワード:
新しいパスワード:
新しいパスワードを再入力してください:
passwd: 全ての認証トークンが正しく更新できました。
[study@ip-172-31-8-2 ~]$
ec2-userの削除例
studyユーザでログイン後、rootに成ってからuserdel
コマンドを叩きます。
[study@ip-172-31-8-2 ~]$ sudo -i
[sudo] password for study:
[root@ip-172-31-8-2 ~]# userdel ec2-user
[root@ip-172-31-8-2 ~]#
GitHubからソース取得
1.fork
元となるリポジトリをGitHub上で自分のリポジトリにコピーします(これをfork
といいます)。
GitHubにログインします。
suzukishouten
で検索すると、今回使用するリポジトリが見つかります。
※ほぼ素のままのCakePHPのファイル一式が入った状態です。
これをforkして自分のアカウントに持ってきます。
赤矢印の[Fork]ボタンをクリックするだけです。
2.開発用サーバにリポジトリをクローン
Fork後、自分のリポジトリに下記のように、Fork元のファイルがまるごとコピーされています。
赤枠の部分にクローン元のURLがありますのでコピーします。今回はhttpsでのアクセスとしますので、https〜で始まるURLをコピーします。
このリポジトリを自分の開発用サーバにCloneします。
study
ユーザでsshログインし、/var/www/study
に移動してから下記のようにgit clone
コマンドを叩きます。下記は私のリポジトリの場合のURL。
cd /var/www/study
git clone https://github.com/ks-ocean/rest-study.git
Cloning into 'rest-study'...
remote: Counting objects: 1465, done.
remote: Compressing objects: 100% (810/810), done.
remote: Total 1465 (delta 445), reused 1459 (delta 444)
Receiving objects: 100% (1465/1465), 1.73 MiB | 575.00 KiB/s, done.
Resolving deltas: 100% (445/445), done.
Checking connectivity... done.
これで、/var/www/study/rest-study
にソースがcloneされました。
試しにアクセスしてみます。
http://(GlobalIP) /rest-study
下記のCakePHPのデフォルトページが表示されればOK!。
シンプルTODOアプリ作成
今回は、シンプルなAPIサンプル作成を行い、HTTPリクエストを送受信するツール「POSTMAN」を使用して作成したAPIの動作確認を行うまでをやります。
1.POSTMANの準備
POSTMANはchromeブラウザの拡張機能です。
下記からインストールします。
※インストールしたら、次回起動のためにブックマークしておいてください。
Postman - REST Client - Chrome ウェブストア
試しに、QiitaのAPIを叩いてみます。
urlは、
http://qiita.com/api/v2/items?page=1&per_page=20
です。
ちなみに、QiitaのAPIマニュアルは⇢Qiita API v2ドキュメント - Qiita:Developer
結果。
この時のqiita.comのサイトを見るとこんな感じ。ちゃんととれている。
これで、作成したAPIのテストが出来ます。
2.プログラミング
いよいよプログラミングです。
GithubからCloneしたソースは、/var/www/study/rest-study
にあります。
sshでログインしてcdしてプログラミングを始めます。
####そのまえに、URLと、CakePHPのController、 Actionの関係について(重要)
プログラミングに入る前に、RESTアプリケーションにおけるURLと、CakeのController, Actionの関係について軽く整理しておきます。
RESTアプリケーションでは、リソースに対してユニークなURIを割付け、それに対してアクセスします。
そのリソースに対してどのような処理を行うかをHttp Methodで指定します。
(例)
URL
- todoリストの一覧
- /rest-study/todo_lists.json
- todoリストのidが'1'の1件
- /rest-study/todo_lists/1.json
行う処理
Http Method | 処理 |
---|---|
GET | 取得する |
POST | 追加する |
PUT | 更新する |
DELETE | 削除する |
CakePHPのController、Actionを含めまとめると
下表の通り、URL、HttpMethod、行う処理、CakePHPのControllerとActionが対応します。
下に、今回作成するソースを載せていますが、この表の通り作成されています。
URL | Http Method | 処理 | Controller | Action |
---|---|---|---|---|
/rest-study/todo_lists.json | GET | TODOリスト一覧を取得する | TodoListsController | index |
/rest-study/todo_lists/1.json | GET | TODOリストのidが'1'の1件を取得する | TodoListsController | view |
/rest-study/todo_lists.json | POST | TODOリストに1件追加する | TodoListsController | add |
/rest-study/todo_lists/1.json | PUT | TODOリストのidが'1'の1件を更新する | TodoListsController | edit |
/rest-study/todo_lists/1.json | DELETE | TODOリストのidが'1'の1件を削除する | TodoListsController | delete |
HTTPレスポンスコードについて
APIの処理結果は、HTTPレスポンスコードで返すようにするのが基本です。
大雑把に言うと、
- 200番台 : 正常終了
- 300番台 : リダイレクト
- 400番台 : クライアントエラー
- 500番台 : サーバエラー
となります。
※参考 HTTPステータスコード - Wikipedia
例)
リソースの追加を行い、成功した場合(POST)は、"201 Created"と返す。
では、プログラミングします!
ソース修正手順
- 開発用ブランチ作成
- gitを使用します。
git branch
で新しいブランチを作ります。 - 今回は、
vol/01
という名前にします。
- gitを使用します。
- ソースを修正する。
- 修正箇所は後述。vimまたはemacsを使いましょう。
- POSTMANで動作確認
- POSTMANを起動し、APIのURLを叩いてみます。
- phpMyAdminでデータ確認
- phpMyAdminを起動してデータの中身を見てみます。
- git初期設定
- gitのユーザ名とメールアドレスを登録します。
- git add
- ファイルをコミット対象にします(ステージング)。
git add ファイル名
です。git add .
とすると変更、追加した全ファイルがステージングされます。
- ファイルをコミット対象にします(ステージング)。
- git commit
- ステージングしたファイルをローカルリポジトリにコミットします。この時点ではGitHubには反映されていません。
-
git commit
とすると、コミットメッセージを入力する画面がvimで開きます。保存すると続行します。 - 面倒なので、
git commit -m "コミットメッセージ"
とすると楽です。
- git push
- GitHubアカウントのユーザ名、パスワードを聞かれるので入力します。
という流れになります。
実際にやってみたスクリーンショットを載せます(画面はMacのTerminal)。
開発用ブランチ作成
実行したコマンド
cd /var/www/study/rest-study/
git branch
git branch vol/01
git branch
git checkout vol/01
git branch
1つ目のgit branch
はclone直後のブランチ確認、2つ目のgit branch
はブランチがvol/01
が作成されていることの確認、ブランチ3つ目のgit branch
はブランチがvol/01
に切り替わっていることの確認です。
ソースを修正する。
まず、app/Config/routes.phpを修正します。
※Vimを使用しました。
実行したコマンド
vim app/Config/routes.php
#〜コピペで編集,保存〜
vim app/Controller/AppController.php
#〜コピペで編集,保存〜
vim app/Controller/TodoListsController.php
#〜コピペで編集,保存〜
vim app/Model/TodoList.php
#〜コピペで編集,保存〜
今回は、下記のソース修正箇所の部分をコピペしました。下記はapp/Config/routes.php
の編集中画面。
他のファイルも同様に vim ファイル名
-> ソースコピペ -> 保存で今回は行きます。
####ソース修正箇所
下記に今回の修正点を書いておきます。
この通り修正すれば動きます!
- 修正したファイル
- app/Config/routes.php
- app/Controller/AppController.php
- 追加したファイル
- app/Controller/TodoListsController.php
- app/Model/TodoList.php
修正ファイルのdiff
※diff表示中の-
(ピンク色)の部分は、修正前のソースから削除し、+
(緑色)の部分を追加してください。
※コピペする場合は、+
の記号を消し忘れないように注意!
/**
* Load all plugin routes. See the CakePlugin documentation on
* how to customize the loading of plugin routes.
*/
CakePlugin::routes();
+/*
+ * API
+ */
+Router::mapResources(array (
+ 'todo_lists',
+));
+Router::parseExtensions('json');
+
/**
* Load the CakePHP default routes. Only remove this if you do not want to use
* the built-in default routes.
*/
require CAKE . 'Config' . DS . 'routes.php';
class AppController extends Controller {
- public $components = array('DebugKit.Toolbar');
+ public $components = array(
+ 'DebugKit.Toolbar',
+ 'RequestHandler'
+ );
}
追加ファイル
<?php
App::uses('AppController', 'Controller');
class TodoListsController extends AppController {
public function index() {
$res = $this->TodoList->find('all');
$this->set(compact('res'));
$this->set('_serialize', 'res');
}
public function view($id = null) {
$res = $this->TodoList->findById($id);
$this->set(compact('res'));
$this->set('_serialize', 'res');
}
public function add() {
$data = $this->request->data;
$res = $this->TodoList->save($data);
$this->set(compact('res'));
$this->set('_serialize', 'res');
}
public function delete($id) {
$res = $this->TodoList->delete($id, false);
$this->set(compact('res'));
$this->set('_serialize', 'res');
}
public function edit($id) {
$this->TodoList->id = $id;
$data = $this->request->data;
$res = $this->TodoList->save($this->request->data);
$res = !empty($res);
$this->set(compact('res'));
$this->set('_serialize', 'res');
}
}
<?php
App::uses('AppModel', 'Model');
class TodoList extends AppModel {
}
POSTMANで動作確認
URLを入力します。
http://GlobalIP/rest-study/todo_lists.json
です。[Send]をクリックします。
でました!予め登録されていた1件です。
※追加、削除、更新も動作しますので、前述のURL, Http Methodのルールに従い、POSTMANの設定を変更して試してみてください。
#####phpMyAdminでデータ確認
http://GlobalIP/phpmyadmin/index.php
にアクセスします。
ユーザ名study
、パスワードstudy
でログインできます。
ログイン後、todo_lists
テーブルの内容を確認したところ。
POSTMANで確認したデータが1件登録されています。
git初期設定
ここまでで、ソースの修正、動作確認まで終わりました。
ここから、gitへのコミット、さらにGitHubリポジトリに反映させるまで進めます。
まずは設定。ユーザ名とメールアドレスを設定します。
※これをやっておかないとgit commit
した時に怒られます。
※ユーザ名、メールアドレスはGitHubアカウントのものと合わせておきましょう。
git config --global user.name "ユーザ名"
git config --global user.mail "メールアドレス"
※git config --global --list
は設定内容を表示するコマンドです。
git add, commit
下記の通り実行します。
git status
git add .
git status
git commit -m "vol/01 complete"
git status
※git status
はファイルの編集、コミット/ステージングの状態を表示するコマンドです。
変化がわかるよう実行しています。
git push
git push origin vol/01
※Githubのユーザ名とパスワードを聞かれるので入力します。
これで、GitHubに反映されました。GitHubの画面で確認してみます。
自分のアカウントのトップページに行き、rest-study
リポジトリをクリック。
ブランチ切り替えのボタンをクリックし、vol/01
ブランチを選択。
app > Controller の順にクリックすると、追加したapp/Controller/TodoListController.php
が表示されました。
ファイル名の部分をクリックするとソースが表示されます。
※この時のURLは、私のアカウントの場合、
https://github.com/ks-ocean/rest-study/blob/vol/01/app/Controller/TodoListsController.phpです。
以上です!
うまくいきましたでしょうか?
コメント/フィードバックお待ちしております。
参加者の方も、そうでない方もお気づきの点があればお願い致します。