イベント支出記録君は、同人誌即売会などでの支出をすぐに記録するためのツール。プリセットに金額を登録しておけば、ワンボタンで支出を記録することができる。CSVダウンロード、TSV形式でのコピー、URLシェアなど、いろいろな方法でデータをエクスポートできる。
下にあるのは、先日のイベントでの自分の支出記録が確認できるURL。
このサービスは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をもっと短くできる方法があったら教えてください。ソースコードはGitHubで公開しています。
2023/5/26 追記
id:onk さんに、Microsoft Learnにいいページがあることを教えてもらいました。