私が歌川です

@utgwkk が書いている

URLにデータを載せつつ、できるだけ短いURLにしたい

sugarheart.utgw.net

イベント支出記録君は、同人誌即売会などでの支出をすぐに記録するためのツール。プリセットに金額を登録しておけば、ワンボタンで支出を記録することができる。CSVダウンロード、TSV形式でのコピー、URLシェアなど、いろいろな方法でデータをエクスポートできる。

下にあるのは、先日のイベントでの自分の支出記録が確認できるURL。

https://sugarheart.utgw.net/event-expenses-tracker/#3AAtzwAAAYeIkjSMzQH0oM8AAAGHiIwcRM0B9KDPAAABh4iIiQ3NAligzwAAAYeIhB9GzQH0oM8AAAGHiEjof80B9KDPAAABh4hGZ8LNA+igzwAAAYeIRHAXzQH0oM8AAAGHiELJ080B9KDPAAABh4hAf3jNASygzwAAAYeIMV7ozQJYoM8AAAGHiC5brc0JxKDPAAABh4grHBPNA+igzwAAAYeIJBG/zQfQoM8AAAGHiCB7ts0B9KDPAAABh4gefvPNAfSg

このサービスはReactを使った単一ページのアプリケーションとなっている。ビルド成果物をAmazon S3上に展開しているだけなので、サーバーサイドの処理が一切ない。そのため、データをURLとして共有するにはひと工夫必要になる。

素朴には、オブジェクトをJSON文字列にしてBase64エンコードしたものURLに含めてしまえばよさそう。が、この方法だとURLが長くなるという欠点がある。先述したURLと同じデータを共有するためにfragment部に1000文字以上使うことになってしまう。データをできるだけ短い文字列に変換できるのが望ましい。

このような場合にMessagePackが使える。MessagePackはデータをコンパクトなバイナリ形式で表現するためのフォーマットである。MessagePackを使えば、JSON文字列よりも短くシリアライズできる。

更に短くシリアライズするための工夫として、オブジェクト型の要素をバラして平坦な配列にすることを考える。以下のような配列があったとして、

[
  {"price":100,"label":"","createdAt":1681602213424},
  {"price":100,"label":"","createdAt":1681602213424},
  {"price":100,"label":"","createdAt":1681602213424},
]

以下のような配列に変換すると、オブジェクト型のキーを持つ必要がなくなり、短くシリアライズできることが期待できる。配列を平坦にすることで、複数の配列ぶんのデータを持たないようにできる。

[
  100, "", 1681602213424,
  100, "", 1681602213424,
  100, "", 1681602213424,
]

実際にこのような変換を施した上でシリアライズしてBase64エンコードしたものが先述したURLになる。fragment部の長さが270文字ほどに収まっている。比べてみれば一目瞭然だと思う。

URL
before https://sugarheart.utgw.net/event-expenses-tracker/#W3sicHJpY2UiOjUwMCwibGFiZWwiOiIiLCJjcmVhdGVkQXQiOjE2ODE2MjM0OTU4MjB9LHsicHJpY2UiOjUwMCwibGFiZWwiOiIiLCJjcmVhdGVkQXQiOjE2ODE2MjMwOTYzODh9LHsicHJpY2UiOjYwMCwibGFiZWwiOiIiLCJjcmVhdGVkQXQiOjE2ODE2MjI4NjIwOTN9LHsicHJpY2UiOjUwMCwibGFiZWwiOiIiLCJjcmVhdGVkQXQiOjE2ODE2MjI1NzI4NzB9LHsicHJpY2UiOjUwMCwibGFiZWwiOiIiLCJjcmVhdGVkQXQiOjE2ODE2MTg2OTIyMjN9LHsicHJpY2UiOjEwMDAsImxhYmVsIjoiIiwiY3JlYXRlZEF0IjoxNjgxNjE4NTI4MTk0fSx7InByaWNlIjo1MDAsImxhYmVsIjoiIiwiY3JlYXRlZEF0IjoxNjgxNjE4Mzk5MjU1fSx7InByaWNlIjo1MDAsImxhYmVsIjoiIiwiY3JlYXRlZEF0IjoxNjgxNjE4MjkxMTU1fSx7InByaWNlIjozMDAsImxhYmVsIjoiIiwiY3JlYXRlZEF0IjoxNjgxNjE4MTQxMDQ4fSx7InByaWNlIjo2MDAsImxhYmVsIjoiIiwiY3JlYXRlZEF0IjoxNjgxNjE3MTQ5NjcyfSx7InByaWNlIjoyNTAwLCJsYWJlbCI6IiIsImNyZWF0ZWRBdCI6MTY4MTYxNjk1MjIzN30seyJwcmljZSI6MTAwMCwibGFiZWwiOiIiLCJjcmVhdGVkQXQiOjE2ODE2MTY3MzkzNDd9LHsicHJpY2UiOjIwMDAsImxhYmVsIjoiIiwiY3JlYXRlZEF0IjoxNjgxNjE2Mjc3OTUxfSx7InByaWNlIjo1MDAsImxhYmVsIjoiIiwiY3JlYXRlZEF0IjoxNjgxNjE2MDQyOTM0fSx7InByaWNlIjo1MDAsImxhYmVsIjoiIiwiY3JlYXRlZEF0IjoxNjgxNjE1OTEyNjkxfV0=
after https://sugarheart.utgw.net/event-expenses-tracker/#3AAtzwAAAYeIkjSMzQH0oM8AAAGHiIwcRM0B9KDPAAABh4iIiQ3NAligzwAAAYeIhB9GzQH0oM8AAAGHiEjof80B9KDPAAABh4hGZ8LNA+igzwAAAYeIRHAXzQH0oM8AAAGHiELJ080B9KDPAAABh4hAf3jNASygzwAAAYeIMV7ozQJYoM8AAAGHiC5brc0JxKDPAAABh4grHBPNA+igzwAAAYeIJBG/zQfQoM8AAAGHiCB7ts0B9KDPAAABh4gefvPNAfSg

URLをもっと短くできる方法があったら教えてください。ソースコードはGitHubで公開しています。

github.com

2023/5/26 追記

id:onk さんに、Microsoft Learnにいいページがあることを教えてもらいました。

learn.microsoft.com