python推しがslimフレームワークについて学んでみる。


参考サイト

環境

ubntu18.04
PHP 7.2.24

経緯

前に一度cakePHPについて触れる機会があり、アイコンヘッダ/メッセージフッタとボタン数個の画面のためにこんな大掛かりなアーキテクチャを理解しなければいけないのか・・とため息をついた記憶があります。

そしたらslim実装のwebアプリが発注先から納品されたりしたので、slimについて学びたいと思った次第。
世間ではマイクロフレームワークと呼ぶらしい。軽量フレームワークとか、この手のキーワードを聞くとこれこそ私の求めていたものではないかと心揺さぶられる。

少し眺めてなんだかpythonのFlaskに似てるなぁと思ったら、Flaskもマイクロフレームワークに位置づけされるっぽい。

導入

マイクロというからには導入も楽なはずと期待。

php入ってる?

(base) websoler@websoler-H110M-S03:~$ php -v
PHP 7.2.24-0ubuntu0.18.04.3 (cli) (built: Feb 11 2020 15:55:52) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.24-0ubuntu0.18.04.3, Copyright (c) 1999-2018, by Zend Technologies

ver7が入ってた。最初っからubuntu18.04に入ってたかも。
標準ライブラリですね、さすがに。

composer必要

pythonにおけるpipのようなもので、phpのモジュールインストールを依存関係を自動解決してやってくれるらしい。

php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
rm composer-setup.php
sudo mv composer.phar /usr/local/bin/composer

公式サイトの通りのはず。公式サイトからインストーラをDLして実行。

slimインストール

composer create-project slim/slim-skeleton slim_server_app

インストールというか、プロジェクトを作ってその下にフレームワーク構築って感じ。
非Web文化圏ではインストールとは呼ばない初見だけど、そういえばWeb界隈ではローカルフォルダに依存関係を集める文化があった気がする。そしてローカルフォルダごと、対象システムへ放り込む(デプロイする)だったと思うので、これはインストールなんだな。

フレームワーク内にスケルトンが用意されてるので、それを元に自分プロジェクト生成。この下に依存ライブラリを含めたslimフレームワークが展開されているはず。

駆動させよう!

cd slim_server_app
php -S localhost:9000 -t public ./public/index.php

phpの組み込みサーバを起動してます。ルートページはslimフレームワーク内のアプリ(index.php)。

ブラウザでlocalhost:9000と打つと、

なんと、ハローワールドだ。

slim内部解析(チョコッと)

フレームワークエンジンの内部フローはあまり追いかけたくないが、
ロードされる./public/index.phpの中をのぞいて抜粋。


$app = AppFactory::create();  <== Webアプリのガラを作り、

$routes = require __DIR__ . '/../app/routes.php';
$routes($app);  <== Webアプリ本体をWebアプリのガラにジョイントし、
$response = $app->handle($request);   <== Webアプリを走らせる。

Webアプリとはつまるところ、URLアクセスに対するハンドラの集合である。
Webアプリの実行とはすなわち、ハンドリングの開始である。(上記handle関数)

ハンドリングとはすなわち、Web界隈ではルーティングと呼んでいるものであり、
url='xxx'に対して、yyを実行する、というルート処理である。
routes.phpにルート処理をぎっしり詰め込んでおいて、ハンドリング処理により必要なルートが叩かれる。

アプリ本体

本体は ./app/routes.php。
このファイルがやってるのはひとつだけ。アプリを定義して、そのインスタンスを返す。

アプリの定義、ここではすなわち、コールバックの定義。
アプリコンポーネント(App)と便宜上呼ぶが、アプリ機能を詰め込んだslimフレームワークコンポーネントがあり、この機能を使って、HTTPリクエストに応じたビジネスロジックを定義する、それがコールバックの実体である。

以下のように、コールバック関数(無名関数)を定義してreturn。
引数で渡されるAppクラスがアプリコンポーネント。

return function (App $app) {...
});

関数内の処理は前述したとおり、ルート処理が詰め込まれている。

$app->get('/', function (Request $request, Response $response) {
   $response->getBody()->write('Hello world!');
   return $response;
});

アプリコアのgetメソッドは文字通り、GETリクエストをさばく。
この場合、ルート'/'に対するハンドラが定義されており、ハンドラ内では
戻り値のボディ(いわゆるHTMLのbodyタグかな)に、Hello worldと出力するよう指示。

スリムなのか?

サーバアプリとしてローカル環境にサクッと構築できるのはスリムなのかもですが、
あくまでCakePHPのような大規模フルスタックに比べて機能を削っているという
意味であって、Webアプリの実装としてはあまりスリム感が・・

Flaskとの比較

slimのwebフレームワークとしての理屈はわかるんですが、マイクロフレームワークであっても、フレームワークとの接点が露出しているのがちょっと重い。
Flaskなら同じ事を以下で実現します。

pip install Flaskとした後に、


from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == '__main__':
    app.run(port=9000)

上記の1ファイルを運用するだけです。

もちろんFlaskはpythonシステムライブラリ群にインストールされており、webフレームワークとは文化が異なるんですが、サーバサイドだし、定点サーバにポンと入れて運用するだけなら、python1ファイルだけ運用すればよいのでFlaskのほうが(フレームワークが完全に隠蔽されているので)とっつきやすい気はします。