js向けMastodonのAPIクライアントライブラリ,megalodonを作った

最近はずっとMastodonクライアントであるWhalebirdを作っている. いわゆるデスクトップアプリを作っていたんだけど,Mastodonへの接続部分はすべてmastodon-apiを使っていた. しかし,これにいろいろ問題があり,最終的にAPIクライアントライブラリを自作するに至った.

www.npmjs.com

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-apitwitをベースに作られており,基本的にすべての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クライアントライブラリがこちら.

github.com

うっかり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をお送りください.