2017-03-04 bath をつかった router の bouzuya/spa-town 0.1.2 をつくった
bouzuya/spa-town 0.1.0 0.1.1 0.1.2 をつくった。
spa-town は bouzuya/bath を基にしたシンプルなルーターだ。paramsFn
ごとに name
をつけた route pattern をつくっておき、複数の route pattern を並べて router にする。 router は path
に対応する name
と params
を返すようになっている。どれにも当てはまらないときは事前に設定された既定値を返す。
コード例は次のとおりだ。
import * as assert from 'assert';
import { result, route, router } from 'spa-town';
const router1 = router([
route('root#index', '/'),
route('users#index', '/users'),
route('users#index', '/users/'),
route('users#show', '/users/{id}', { id: /^\w+$/ }),
route('users#show', '/users/{id}/', { id: /^\w+$/ })
], result('root#notfound', {}));
assert.deepEqual(router1('/'), result('root#index', {}));
assert.deepEqual(router1('/users'), result('users#index', {}));
assert.deepEqual(router1('/users/'), result('users#index', {}));
assert.deepEqual(router1('/users/123'), result('users#show', { id: '123' }));
assert.deepEqual(router1('/users/123/'), result('users#show', { id: '123' }));
assert.deepEqual(router1('/no-match'), result('root#notfound', {}));
bath の活用例になっている。一度は bath の examples/ に入れたのだけど、何かに使ってみたくなり、リポジトリを分けて npm package を公開した。
bath よりも実際のアプリケーションにありそうな形になっているはずだ。 path を解釈して、対応する name と params を返す。対応するものを選ぶあたりが routing ……と言っていいのかな。 router の範囲はさまざまだが、わりと小さい範囲に留めたつもりだ。
末尾 /
のために別の route
を用意しないといけないあたりは、最終的な利便性よりも学習性を採っている。ほかにも大文字小文字の区別や、 directory ごとの入れ子構造などを取りたい可能性もありそうだが、捨てている。 server-side を考えると method
も判定に含めたいかもしれない。
入れ子構造はわりと欲しい気がするのだけど、優先順位が複雑になりそうなので避けている。現状は単純な Array
なので上から順に見て、なければ default という単純な挙動だ。
上記のような要望やあるいは他の要望も、必要に応じて変更するかもしれないし、別物としてつくるかもしれない。これくらいならアプリケーションごとに実装しても良いとは思うので、無理にこれを使う必要はない。