はじめに
SENSYN Robotics(センシンロボティクス)の中山です。
Webアプリやそのインフラ周りと、Web側とドローンの接続を行うデバイスドライバ的な部分を担当しています。
ミドルウェアのAPIが想定していない値をミドルウェアの後ろにいるカスタムソフトウェアに渡したいことがあり、そのための方法の一つを紹介します。
なにをしたいか
下記の図のような呼び出しの流れで、フロントエンドとバックエンドは自作、ミドルウェアはソースコードが公開されていない製品を使っています。フロントエンドからミドルウェアのAPIを呼び出すと、ミドルウェアが引数に応じた処理をしてバックエンドを呼び出します。
{フロントエンド} --> {ミドルウェア} --> {バックエンド}
このとき、ミドルウェアのAPIが想定しない値をバックエンドに渡して処理をしたいケースがあります。実際にあったのは下記のようなパターンです。
- 正の値しか受け付けないAPIを経由して、バックエンドに負の値を渡したい
- フロントエンドが渡すオブジェクトが特殊な種別であることを、バックエンドに伝えたい
解決方法
ミドルウェアのAPIは変更できないため、APIに渡す値に細工をし、バックエンドでその細工を解釈できるようにする、というのが基本的な方法になります。
例として、正の値しか受け付けないAPIを経由して、バックエンドに負の値を渡したいケースを考えます。
このときは渡したい値が倍精度の浮動小数点型(double)で、実際には整数部が4〜5桁、小数点以下は二桁までの精度があれば十分でした。ということは、それより下の桁に負であることを示す情報を入れてやれば、バックエンドに負の値を渡せそうです。そこで、こんなアイデアを思いついて実装しました。
- フロントエンドの処理
- 正の値の場合
- 小数点二桁で四捨五入して0.001を足す (
987.654
→987.65
→987.651
)
- 小数点二桁で四捨五入して0.001を足す (
- 負の値の場合
- 小数点二桁で四捨五入して絶対値を取り、0.006を足す (
-987.654
→-987.65
→987.65
→987.656
)
- 小数点二桁で四捨五入して絶対値を取り、0.006を足す (
- 正の値の場合
- バックエンド
- 小数点以下三桁が0.005未満なら、小数点以下三桁を切り捨てる (
987.651
→987.65
) - 小数点以下三桁が0.005以上なら、小数点以下三桁を切り捨て、符号を負にする (
987.656
→987.65
→-987.65
)
- 小数点以下三桁が0.005未満なら、小数点以下三桁を切り捨てる (
フロントエンドで足している値とバックエンドの判定で使う境界値が異なるのは、浮動小数点の誤差による判定間違いを避けるためです。
この例では1bitの情報(正負)を渡しているのでこのようになっていますが、判定の境界を細かく区切ることでバックエンドに伝える情報量を増やすことも可能です。
問題点
当然ですが、フロントエンド、バックエンドの開発者がこの手法を使っていることを知っている必要があり、気をつけてメンテナンスしないと簡単に壊れます。コードも理解しにくいものになるため、本当に他に方法がないとき以外は使うべきではありません。
必要になった場合も、ミドルウェアの開発側に拡張のリクエストをし、それが実装されるまでのつなぎとしてこの手法を適用するのがいいのではないかと思います。
まとめ
- APIのデータ型が持つ情報量より送るべき情報量が少なければ、他の情報を混ぜ込んでAPIの向こう側に伝えることができる
- メンテナンスが辛くなるので、乱用すべきではない