reititClojure/Scriptの高速なルーター。はい30文字。

brown wooden pathway on green grass field near brown rocky mountain under white clouds during daytime

もうちょっと長文でいくと、フィンランドのメトシン社が出しているルーターライブラリであって、パフォーマンスにしっかり重点を置きながらも惚れちゃうぐらいの機能の豊富さを誇っている。フロントエンド(ClojureScript)で使ったことが(まだ)ないので省いて、サーバー側での振る舞いとかに関してまとめよう。

まずは引っかかるところ

ほとんどコンパイル時

reititがあんだけのパフォーマンス発揮できるのは、可能な限りの処理をコンパイル時に行って実行時で必要最小限のことしかやらないのが一つの理由。入れ子になっているルートを全部平にしてそれぞれにミドルウェアを展開して、ルート郡に最適な選択方法を適応する。

green track decor

強力な実装方式ではあるが、注意しなければ問題の原因にもなりうる。例えば状態ありの(ステートフルな)ミドルウェアを使うと、それが各エンドポイントに複製されるので共有されると期待した状態が共有されない。別関数になっちゃってるから当たり前。なのでring.middleware.session/wrap-sessionのような状態ありきのミドルウェアを使うとルートと別にその初期化を行って、その結果を渡す回避策を取る必要がある

バッティングしないでね

ルートがバッティングすると、最適な探索方法はあれべなくなって、そうじゃないルートと比べてパフォーマンスがかなり落ちてしまう。これはもちろんreititの問題じゃなく、バッティングしちゃうルートが悪いけど、違和感覚えるかもしれないから記載しておく。

elephant walking during daytime

例えばマストドンのAPIを実装しようとすると、あっちこっちで派手にバッティングしている。それで比較して5ルートしかないhello worldより遅いのはreititの問題ではないとだけ認識しよう。

惚れるやつ

さてちょっとアレなところも片付けたし、気を取り直して最高に嬉しいところを見てみよう。パフォーマンスは本家がドキュメントにしっかり自慢しているからあまり触れないつもりだけど、とりあえずそこそこかなりめっちゃ速い。

ルート引数の変換

エンドポイントの処理を行う関数いわゆるハンドラに渡す引数は色々あり得る。

  • パスに入った情報: /api/users/:id/profile からの id
  • GETのクエリの情報: /api/users/:id/profile?full=true からの full (値は true )
  • POSTしたJSONの情報
  • POSTしたフォームの情報

エンドポイントの定義にその処理に必要な情報のもとの場所と形式を定義すれば、基本的に文字列として飛んでくるリクエストの中からreititがよしなにその形式に沿って数値にしたりしてくれる。形式の定義としてClojureのspecもちろん、metosin社製のdata-specやMalli、PlumaticのSchemaも対応している。形式を満たさないリクエストが飛んでくる時にエラーにするかどうするかも設定できる。

同様にサーバーから返すレスポンスにも形式を強制できる。さらに開発やテスト環境でゴリゴリ固めて厳しい設定にして、お客様に不本意のエラーは見せたくない本番ではちょっと緩めて動かす手すらある(いいかは置いといて)。

Railsでルートの定義はこっちで、引数の定義はまずなく、バリデーションかけるとしたらコントローラーかな?とは大違いできれいに一箇所にルートにその情報が揃う。

multipartのリクエストだけはちょっと苦手。

Swagger

ルートの情報だけでswagger.jsonを出力してくれて、SwaggerUIまで内蔵のモジュールすらある。これだと個別にSwaggerの形式に沿ったJSONを手動で書いたり、SwaggerUIを探してわざわざ開発環境に入れるとかもいらなくなる。

API開発しているところでこのおかげでめっちゃ早く動けて、コード変更した瞬間にブラウザからAPIを簡単に試せるありがたさは感動する。ルート情報にあるもの(:parameters, :responses とか)は勝手にSwaggerに展開されるし、そこにはない情報でも(:produces, :consumes とか)は :swagger キーでエンドポイントの情報にいくらでも追加できる。

強いていう課題としてはOpenAPI 3のサポートはまだというところかな…

しめ

reititはmetosin製だけあってClojureのライブラリの中でしっかりと継続的にメンテされて、使っているコミュニティも活発なので今日明日で捨てられもしないだろう。そこにパフォーマンスと機能の豊富さを加えると、いかにもプロダクションで使っていいライブラリだと明らか。使っているし。