Web APIでint64を返すのをやめよう

こんにちは、 @p1ass です。

久々にAPIを書いていて罠にハマったのでメモしておきます。

tl;dr

遭遇したバグ

最近個人で開発した Memoito(めもいと) というWebサービスのAPIを書いているときの出来事です。

MemoitoではIDとしてTwitter社が開発した snowflake を採用しています。

これは、int64のID生成器で、TimestampとSequence Number、Machine IDを元に生成されます。実運用上問題のない程度に一意性が担保されている上に、UUIDよりも見た目的にスッキリしたIDなため、URLに使っても良さそうということで採用しました。

さて、snowflakeを使ってAPIを書いたわけなのですが、Vue.jsで書かれたクライアントであるデータをGETし、そのデータを加工してPUTすると、何故か違うIDとなってPUTされサーバが500返すというバグが発生しました。

原因

原因はJavaScriptの数値型は64ビット倍精度浮動小数点数であり、整数値は53ビット分までしか正しい値にならないのが原因でした。

Developer Consoleを眺めていると、最初の方の桁は合っているのに最後の方が0で丸められているので、すぐ気が付きました。

対応

そのままint64で値を返すわけには行かないので、API側でstringにして返すようにしました。

nya-n.png 誤差が見える

まとめ

53ビットを超える整数値を返す機会はないので、なかなか気が付きにくいと思います。

int64を返すときは気をつけましょう。

Top