CentOSにHaskellをインストール
CentOSにHaskellをインストール
インストール
sudo wget http://sherkin.justhub.org/el6/RPMS/x86_64/justhub-release-2.0-4.0.el6.x86_64.rpm sudo rpm -ivh justhub-release-2.0-4.0.el6.x86_64.rpm sudo yum install haskell
起動
$ ghci GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude>
終了
Prelude> :q Leaving GHCi.
インストール済みパッケージリスト
$ ghc-pkg list /usr/local/lib/ghc-7.6.3/package.conf.d Cabal-1.16.0 array-0.4.0.1 base-4.6.0.1 bin-package-db-0.0.0.0 binary-0.5.1.1 bytestring-0.10.0.2 containers-0.5.0.0 deepseq-1.3.0.1 directory-1.2.0.1 filepath-1.3.0.1 ghc-7.6.3 ghc-prim-0.3.0.0 haskell2010-1.1.1.0 haskell98-2.0.0.2 hoopl-3.9.0.0 hpc-0.6.0.0 integer-gmp-0.5.0.0 old-locale-1.0.0.5 old-time-1.1.0.1 pretty-1.1.1.0 process-1.1.0.2 rts-1.0 template-haskell-2.8.0.0 time-1.4.0.1 unix-2.6.0.1 HTTP-4000.2.10 monads-tf-0.1.0.1 mtl-2.1.2 network-2.4.2.1 parsec-3.1.4 text-1.0.0.0 transformers-0.3.0.0
パッケージのインストール
cabal update cabal install パッケージ名
Git
Git
いまさら感ありますが、
時間があったのでGitについて基本を整理してたので、
メモ的な感覚で書きます。
・適当な場所にディレクトリを作成して『git init』 でリポジトリ作成
・リポジトリを共有化する場合は、bare、sharedオプションを付与して『git init』
・gitの初期化が完了したら、gitユーザーを作成しておいて、
gitユーザーが書き込み可能な状態にグループを変更しておく
・gitプロトコルでアクセスする場合は、リモート側でgit-daemonをインストール&起動
※誰でもアクセスできちゃうので、セキュリティ的には良くない
・リモートへは基本、sshプロトコルでアクセスするほうが良い
・外部からsshできるようにするために、リモート側で「/home/git/.ssh/authorized_keys」(パーミッション600)を作成。
そのファイル内に、アクセス元の公開鍵を登録。
・ブランチ管理には「git flow」を利用する
・ローカルもしくはリモート側で『git flow init』しておく
・git管理ツールは、gitlabが良いかな。
FacebookのOSSの「Phabricator」はちょっと複雑なので、余計な機能がないgitlabがよいかと。
・ローカルでは、sourcetreeというツールがいいですね。(Win、Mac)
Phalcon 1.2.4 (PHP Framwork)::APIスケルトン その2
Phalcon
前回の記事に記述したディレクトリ構成に、
interfacesというディレクトリを追加してみました。
├─collections │ UserCollection.php │ ├─config │ config.php │ loader.php │ services.php │ ├─controllers │ ControllerBase.php │ UserController.php │ ├─interfaces │ ├─request │ │ ├─fields │ │ │ CommonFields.php │ │ │ UserFields.php │ │ │ │ │ └─validation │ │ │ UserValidation.php │ │ │ ValidationBase.php │ │ │ │ │ └─custom │ │ Custom.php │ │ Date.php │ │ Type.php │ │ │ └─response │ │ ResponseBase.php │ │ UserResponse.php │ │ │ └─fields │ UserFields.php │ ├─models └─views
追加したinterfacesディレクトリには、
名前の通り、主に、request、responseに関するクラスを
入れました。
サンプルソース
controllers/UserController.php
require __DIR__ . '/../interfaces/request/validation/UserValidation.php'; require __DIR__ . '/../interfaces/response/UserResponse.php'; class UserController extends ControllerBase { public function getUser() { $req = $this->input(); //バリデーション処理 $uv = new UserValidation(); $valid = $uv->getUserValidation($req); if ($valid->count()) { //Error $msg = $valid[0]->getMessage(); $this->output(400, UserResponse::errorResponse(400, $msg)); return; } //DB操作 //レスポンス $this->output(200, UserResponse::getUserResponse({DB操作した結果の配列})); } }
コントローラーでは、基本的に全て共通して、
リクエストを取得 ↓ バリデーションチェック ↓ エラーの場合は、エラーレスポンスを返す ↓ エラーがない場合は、DB操作を何かする ↓ レスポンスデータを作成し、JSONを返す
といった感じですかね。
バリデーションチェックでは、
nullチェックや、型チェック、値チェック、長さチェックなど
基本的なことをやります。
また、リクエストフィールドに対するバリデーションチェックは、
APIの種類に関係なく、基本は同じはずだと思います。
(nullがOKの有無はAPIの種類によって異なる場合はあるかと思います。)
なので、APIで扱う全てのリクエストフィールド情報は、
interfaces/request/fields/CommonFields.php
に記述するようにしました。
内容としては、
フィールド名、フィールドに対して使用するバリデーションインスタンス
となります。
サンプルソース
interfaces/request/fields/CommonFields.php
<?php use Phalcon\Validation\Validator\PresenceOf, Phalcon\Validation\Validator\InclusionIn, Phalcon\Validation\Validator\Email, Phalcon\Validation\Validator\Between, Phalcon\Validation\Validator\StringLength; class CommonFields { //Request Fields protected $_fields; public function __construct() { $this->_fields = array( 'sex' => array( 'default' => array( new PresenceOf(array( 'cancelOnFail' => TRUE, )), new InclusionIn(array( 'domain' => array('male', 'female'), 'cancelOnFail' => TRUE )), ), 'custom' => array( new Type(array( 'type' => 'string' )), ), ), 'birthday' => array( 'default' => array( new PresenceOf(array( 'cancelOnFail' => TRUE, )), ), 'custom' => array( new Type(array( 'type' => 'integer' )), new Date(array( 'format' => 'Ymd' )), ), ), ~省略~ ); } public function getFields() { return $this->_fields; } }
バリデーションの部分が
defaultとcustomに分かれているのは、
Phalconで用意されているバリデーションクラスと、
自前で用意したバリデーションクラスを区別するためです。
上記のクラスでは、APIの全てで扱うフィールドを設定したので、
interfaces/request/fields/UserFields.php
では、各APIで扱うフィールドを記述するようにしました。
サンプルソース
interfaces/request/fields/UserFields.php
namespace Interfaces\Request\Fields { class UserFields { static public function getUserFields() { return array( array('sex', TRUE), array('birthday', TRUE), ~省略~ ); } } }
TRUEの部分は、NOT NULLのフラグとしています。
ここをFALSEにすると、バリデーションチェックで、
nullチェックは行わないようにします。
バリデーションチェックして、OKだったら、
何かDB操作して、レスポンスを返さなければいけません。
リクエストと同様にして、
各APIごとにレスポンスのフィールドも設定するようにします。
サンプルソース
interfaces/response/fields/UserFields.php
<?php namespace Interfaces\Response\Fields { class UserFields { static public function getUserFields() { return array( 'sex', 'birthday', ); } } }
DBから得られた結果から、上記で設定したフィールドをもとに
必要なものだけを取得して、レスポンスを作成し、クライアントに返します。
ここまで、ソースを抜粋しながら、簡単な説明を記載してきました。
DB操作以外の部分は、
API実装前に存在している仕様書から全て設定できる範囲なので、
実装の半分くらい?は簡単にできるのではないかなと感じてます。
Phalcon 1.2.4 (PHP Framwork)::APIスケルトン
Phalcon
Phalcon Frameworkを利用してAPIを実装したときのスケルトンを紹介します。
本家ドキュメントでは、
http://docs.phalconphp.com/en/latest/reference/micro.html
を参考にしました。
ディレクトリ・ファイル構成
基本構成は、Phalcon Developer Toolsを使用して作成しました。
phalcon-micro │ .htaccess │ app.php │ ├─.phalcon ├─app │ ├─collections │ │ UserCollection.php │ │ │ ├─config │ │ config.php │ │ loader.php │ │ services.php │ │ │ ├─controllers │ │ ControllerBase.php │ │ UserController.php │ │ │ ├─models │ └─views │ ├─logs │ └─public │ .htaccess │ index.php │ ├─css ├─files ├─img └─js
API用に追加した部分
コントローラー
Developer Toolsで作成すると、MVしかない。コレクション
http://docs.phalconphp.com/en/latest/reference/micro.html#using-controllers-as-handlers
サンプルソース
app.php
※ルーターの役割
<?php //APIのバージョン $version = "1.0"; //未定義のパスにアクセスした場合に実行される $app->notFound(array(new ControllerBase(), "notFoundAction")); //コレクションのインクルード include __DIR__ . '/app/collections/UserCollection.php';
UserCollection.php
<?php use Phalcon\Mvc\Micro\Collection as MicroCollection; $userCollection = new MicroCollection(); //メインコントローラー $userCollection->setHandler(new UserController()); //コレクション内での共通prefix $userCollection->setPrefix("/{$version}/user"); /** * ユーザー情報取得 * * http://api.sample.com/1.0/user/ * に対して * GETでアクセスすると * UserControllerのgetUserメソッドが実行される */ $userCollection->get("/", "getUser"); /** * ユーザー登録 * * http://api.sample.com/1.0/user/register/ * に対して * POSTでアクセスすると * UserControllerのpostUserメソッドが実行される */ $userCollection->post("/register", "postUser"); $app->mount($userCollection);
UserController.php
<?php class UserController extends ControllerBase { public function getUser() { } public function postUser() { } }
ControllerBase.php
※全てのコントローラーのベース
<?php use Phalcon\Mvc\Controller; class ControllerBase extends Controller { /** * * @param int $code * @param array $content */ protected function output($code, $content=array()) { //Header $this->response->setContentType('application/json') ->setStatusCode($code, null) ->sendHeaders(); //Body $this->response->setJsonContent($content) ->send(); } public function notFoundAction() { $this->output(404); } }
Phalcon 1.2.4 (PHP Framwork)::コントローラー
Phalcon Framework
コントローラー
http://docs.phalconphp.com/en/latest/reference/controllers.html
リクエスト
GET基本
http://localhost/blog/posts/show/2012/the-post-title/
※GETクエリには、パラメータの値だけで、変数名は不要。
以下のようにActionメソッド関数に引数を設定することで、取得できる。
URLに設定されているパラメータ値と、メソッドの引数は順序的1対1の関係にある。
<?php class PostsController extends \Phalcon\Mvc\Controller { public function indexAction() { } public function showAction($year, $postTitle) { /* $year に 2012 $postTitle に the-post-title がアサインされる */ } }
GETパラメータにデフォルト値を設定する場合は、以下のようにする。
public function showAction($year=2012, $postTitle='some default title') { }
もし、URL形式を以下のようにしたい場合は、
http://localhost/blog/posts/show/?year=2012&title=the-post-title
以下のようにパラメータ値を取得できる。
public function showAction() { $year = $this->request->getQuery('year'); $title = $this->request->getQuery('title'); }
GET以外のPOSTなども上記と同じような理屈で対応できる。
リクエストに関するクラスは、 Phalcon\Http\Request
レスポンス
レスポンスに関するクラスは、 Phalcon\Http\Response
フォワード
$this->dispatcher->forward(array( "controller" => "users", "action" => "signin" ));
初期化メソッド
※ “__construct”は非推奨です。
※beforeExecuteRouteイベントが成功した場合のみ実行されます。
public function initialize() { }
登録サービスへのアクセス
Phalcon\Mvc\Controllerを継承したコントローラーであれば、
以下のようにしてDIにアクセスできます。
$this->di; or $this->getDI();
セッションデータ
セッションに関するクラスは、 Phalcon\Session\Bag
以下のようにして、値のセット、取得ができます。
<?php class UserController extends Phalcon\Mvc\Controller { public function indexAction() { $this->persistent->name = "Michael"; } public function welcomeAction() { echo "Welcome, ", $this->persistent->name; } }