プログラマ人生後半戦のテーマ

最近考えているのは、Webアプリケーションフレームワークとの付き合い方とか、移植性の高いWebアプリのアーキテクチャパターンとか、そんなことである。先日公開した flask-skinny はその一環だ。定年まで20年を切ったプログラマ人生の後半戦、まずはこのテーマに自分なりの結論を出したいと思っている。

なぜそんなことを考えているかといえば、これまで勤めてきたいくつかの企業で、フレームワークのアップグレードに追従できなくなっているアプリを見てきたからである。2015年に入社した企業ではRails 2が使われていた。Rails 4がリリースされたのは2013年である。テストコードはなかったから、真面目にアップグレードするとすれば、まずテストコードを書き、Rails 3への移行を試すことになる。当時は他のタスクに追われ、そんな余裕はなかった。2020年の今でも、似たような状況に陥っているWebプログラマは少なくないのではないか。

もういい加減、そんなWebアプリ、そんな負債は生み出したくない。フレームワークのアップグレードに追従しやすい、もしくは別のフレームワークに乗り換えやすい、あるいは他のプログラミング言語に移植しやすい、そういうWebアプリが書きたい。

では、そのためにはどうしたらよいのか。それをプログラマ人生の後半戦の最初のテーマに据えようというわけである。


今のところ、なんとなく考えているのは以下のようなことだ。

  • フルスタックフレームワークは避ける
    • いずれ心中することになるから
  • ルーティング処理は自前で書くか、フレームワークに任せる
    • ルートをYAMLなりJSONなりで定義し、自前で処理するのが理想的
    • とはいえ、移植時にルート定義を書き直すのはそこまで負担にはならなさそう
  • リクエストやレスポンスの抽象化はプログラミング言語かフレームワークに任せる
    • WSGIやらRackやらは抽象度が低すぎ、そのまま扱うのは厳しい
    • とはいえ、抽象化処理を自前で書くのは車輪の再発明すぎる
    • Goの net/http がよさそうに見える
  • データアクセスレイヤへの依存性をビジネスロジックに注入するのはコントローラの役目
    • そこまでしてくれるフレームワークはないから
  • ビューテンプレートには Mustache を使うHTTPレイヤのテストを書く
    • いずれも、他の言語に移植しやすくなるから
  • Intent-Responseパターンを活用する
    • flask-skinnyで提案したアーキテクチャパターン。詳細は近日公開予定の別記事で

以上のようにまとめてみると、Goなら、超うすうすフレームワークを自前で書けば、移植性の高いWebアプリが書けそうな気がしてきた。フレームワークに必要な機能は下記のみ。

  1. JSONなりYAMLなりでルートが定義できるルーティング機能
  2. 外部への依存性(データアクセス、テンプレートエンジン、etc.)をWebアプリに注入できるDI機能
  3. Intent-ResponseパターンでWebアプリを呼び出す機能

1と2は、いい感じのライブラリがすでにあるかもしれない。3は、flask-skinnyで実現したとおりで、さほど難しいものではない。

というわけで、直近のタスクは上記フレームワークを作ることとなった。Go初学者なので、焦らず進めていく。

リリースチェッカーをいろいろ改善した(limit_reqとか)

前回の記事の流れで、久しぶりにリリースチェッカーの改善を進めている。ここ数日で実施した内容は以下の通り。

  • 発売日の表示バグを修正した。発売年以外未登録の商品の発売日が「2017T」のように表示されていた。
  • Googleアナリティクスを導入した。多くの方にリリースチェッカーを使っていただくべく、分析のために入れた。
  • モバイル用のCSSを調整した。見やすくなったはず。
  • RSSに含まれる和書の数を増やした。PA-API v5のドキュメントには、Search Indexを「Books」にすると和書が返ってくると書かれている。だが、実際には洋書も返ってきてしまう。なので、2ページ目(ItemPage = 2)まで検索し、不足分を補うようにした。
  • CircleCiでDockerイメージをビルドするようにした。Docker Hubの自動ビルドを使っていたのだが、開始まで10分以上待たされるのが我慢できなくなった。
  • PA-API呼び出し失敗時の404エラーを修正した。PA-API v5では呼び出し回数の制限が厳しくなっている。呼び出し失敗が続いた場合、リリースチェッカーでは503エラーを返していたつもりだった。が、実際には404が返っていた。
  • RSSクローラーのアクセス数を制限した。Apacheのプロセスが不足し、タイムアウトすることがあった。前段に置いているNginxのngx_http_limit_req_moduleを使って制限したところ、サービスが安定した。

ぼくとしては「クローラーのアクセス数制限」が会心だった。Nginxの設定ファイルを抜き書きすると、こうなる。

limit_req_zone $limit_req_per_ip zone=rss_per_ip:10m rate=1r/s;

server {
    location /rss {
        limit_req zone=rss_per_ip burst=2 nodelay;
        limit_req_status 429;

        set $limit_req_per_ip $binary_remote_addr;
        if ($http_x_requested_with = XMLHttpRequest) {
            set $limit_req_per_ip "";
        }
    }
}

クローラーだけを制限対象にしたいので、ブラウザからXMLHttpRequestでRSSにアクセスした場合は除外している。

ngx_http_limit_req_moduleのことは初めて知った。便利。

リリースチェッカーにはまだまだ改善ポイントがあると思う。引き続きやっていく。

情報処理安全確保支援士と情報処理学会をやめた

  • 情報処理安全確保支援士の登録消除届出書をIPAに出した。現時点では登録のメリットが感じられなかったため。
  • 情報処理学会を退会した。何の活動もできていなかったため。

ぼくの短所は、本気で取り組む気概もないのに、衝動的にいろいろ手を出す点だと思っている。プログラミング講師も、OSSマニュアルの翻訳も、ウェブデザイン技能検定の検定委員も、もはや何も取り組めていない。いつも他のことに興味が移って、二の次になってしまうのだ。

ぼくが今、家族以外の誰かの役に立っているとしたら、本業のお客様や同僚たち、そしてリリースチェッカーのユーザの皆様くらいだろう。ならば、何よりそれらの方々のために尽力すべきなのだ。というわけで、遅きに失した感はあるものの、広げすぎた風呂敷を畳むことにした次第。

プロフィール
Web開発者。現在の関心事はシステム品質の改善(特に性能効率性と保守性)。JAPAN MENSA会員。
カテゴリ別アーカイブ
記事検索