最近はずっとMastodonクライアントであるWhalebirdを作っている. いわゆるデスクトップアプリを作っていたんだけど,Mastodonへの接続部分はすべてmastodon-apiを使っていた. しかし,これにいろいろ問題があり,最終的にAPIクライアントライブラリを自作するに至った.
mastodon-apiの問題点
POSTのパラメータ
mstdn.jp等では問題なく使えていたが,ある時friends.nicoでログインした場合に投稿できないという問題が発覚した.
サーバ側の問題かと思いいろいろ調べたのだが,どうやらcurlで投稿すると普通に投稿できた. これはAPIクライアントが怪しいと思って調べたところ,mastodon-apiはPOSTリクエスト時のパラメータをbodyではなくURLのquery stringとして埋め込んでいることが判明した.
https://github.com/vanita5/mastodon-api/blob/master/src/mastodon.js#L248-L267
これはRESTとして筋が悪い.この先,他のサーバでも投稿できなくなる可能性が高いと判断した.
Callback
また,mastodon-apiはtwitをベースに作られており,基本的にすべてのREST APIリクエスト結果はcallbackで受け取る設計になっている.
しかし,今作っているプロダクトはほとんどPromiseを返すことを前提にしており,リクエストをするたびに毎回Promiseを生成し,callback内容に応じてresolveしたりrejectしたりしている. これも筋が悪い. できれば今風のクライアントらしく最初からPromiseで結果を返してほしいと思っていたため,乗り換えるにはいい時期かと思った.
mstdn-apiという希望
他に有用なクライアントがないかどうかを調べた結果,Promiseを返していて,POSTリクエストのパラメータをbodyに付与しているライブラリとしてmstdn-apiを発見した. typescriptだたし,なかなか使えそうな感じだったので一部導入してみたのだが,これにもやはり問題があった.
streamingのstopが無限ループに落ちる
REST APIはなんの問題もなく,ちゃんとPromiseを返してくれて使いやすかった. streamingに関してもサンプルが用意してあり,問題なく動作したように見えたのだが,streamingを停止したいと思ったときに問題が発生した.
call stackを使い果たして例外をはくようになってしまった. これはソースをみると納得するものだった.
closeメソッドを呼ぶと一見closeしてくれるように見えるのだが,
https://github.com/onsen-ui/mstdn-api/blob/master/src/streamlistener.ts#L59-L63
実はconnect時にcloseのcallbackが設定されている.
https://github.com/onsen-ui/mstdn-api/blob/master/src/streamlistener.ts#L80-L84
で,_onCloseでは
https://github.com/onsen-ui/mstdn-api/blob/master/src/streamlistener.ts#L100-L109
error発生時にemitしている.
そのemitしたerrorはここで拾われ,
https://github.com/onsen-ui/mstdn-api/blob/master/src/streamlistener.ts#L94
再び_onCloseが呼ばれる.
つまり,_onCloseでエラーが発生すると無限ループに陥る.
これは筋というか設計が悪い.
プルリクエストを送ることも考えたが,最近更新されておらず,アクティブに開発されているライブラリかも怪しい. そのうえ設計の大幅変更をしたいとなると,これは自分で作ったほうが早い.
megalodon
というわけで自作したAPIクライアントライブラリがこちら.
うっかりtypescriptが楽しかったのでtypescriptで書いている.
REST API部分はほとんどmstdn-apiと同様だが,リクエストをさばくのにsuperagentではなくaxiosを使っている.
axiosなので,たとえばmultipart-form-dataをPOSTしたくなったような場合は,axiosと同様のパラメータを渡せば基本的に動作する.
streamingはmastodon-apiを参考に,同じくtypescriptで書いている.
こいつは停止時に無限ループに陥るようなヘマはしていない.
なおテストはまだ書いていない.オブジェクトのパース等はテストを書いたほうがいいかなーとは思っている.
Whalebird
Whalebirdでは1.3.3から,APIクライアントライブラリをmegalodonに変更している.すべてのAPI接続をすでに入れ替え済みである.
なので,friends.nicoでも使えるようになっている.
WhalebirdもmegalodonもOSSなので,もしバグや要望がある場合には,是非IssueまたはPullRequestをお送りください.