2016-07-16 bouzuya/bath をつくった
bouzuya/bath をつくった。その経緯として router の設計に関することなどを書く。
bouzuya/bath は simple な path template 。'/users/:id'
と { id: '123' }
から '/users/123'
をつくったり、その逆をするもの。現状の実装は pillarjs/path-to-regexp の wrapper 。おそらく template の構文を含めて根本的に書き直す。ちなみに TypeScript 2.0 beta を使っている。今回は触れない。
bouzuya/alertwil をつくる過程で router について考えた。次の tweet からたどれる。
router は path -> action name + params, action name + params -> path ができれば良いのでは。action は name であって、 action を呼び出すのはまた別で良いのでは。
— bouzuya (@bouzuya) 2016年7月16日
改めて書く。
bouzuya/alertwil で RoR: Ruby on Rails でいう path/url helper がほしくなった。しかし、現状は router が controller を直接参照しており、愚直に実装すると循環参照をつくってしまう状態に陥った。そこで浮かんだ疑問がある。
router が action を呼び出すのではなく path -> action name + params やその逆で十分じゃないか。
RoR は router と controller を分割している。params からの取り出しは controller (action) の役割だ。ただし RoR だと naming convention で振り分けの問題を疎結合なまま解決する。これは文字列で action や view を指定できるということだ。
ひとまず router と controller の結合方法は保留しつつ、ここまでで simple-router-b の Gist を書いた。これは bouzuya/boa-router に近い挙動だ。
書いたことで simple-router-b における問題を見つけた。 HTTP method を踏まえた振り分けだ。Single Page Application の routing においては GET あるいは HEAD しか使わないので問題にならない。boa-router はこのおかげで問題にならない。しかし標準的な Web Application をつくると method で振り分けられないのは問題になる。……かといってそこに対応すると simple じゃなくなりそうだと感じた。
ぼくが RoR でもいびつだと感じている部分なのだけど、RoR の routing は path helper が複数の route で重複しておりいびつになる。これは routting と path helepr の負っている役割や単位が異なり、本来なら分割できるからだ。
そこで path helper や template + path -> params に相当する部分を simple-router-b から分離することにした。routing の役割を負わせるのは不適切なので単純に path を解決する関数に。
ここまでで bath の Gist を書いた。実態としては path-to-regexp の劣化版だ。ただ path-to-regexp は API がやや分かりづらいのと、 '"Reverse" Path-To-RegExp' の意味がよく分からない。それをふまえると simple な path template である bath に価値はあると思った。
で、bouzuya/bath をつくった。まだ未完成だけど、ねらいは routing からの path template 部分を分離する。競合は path-to-regexp だけど、 bath のほうがより実装を隠している。