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;
}
}