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

1 min read | #JavaScript #JSON #API

こんにちは、 @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