blog.bouzuya.net

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 からたどれる。

改めて書く。

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 のほうがより実装を隠している。