>100 Views
March 25, 25
スライド概要
ユニークビジョン株式会社CTOです。
APIラッパーのコツ ユニークビジョン株式会社 青柳康平
ご紹介 ユニークビジョン株式会社 SNSマーケティングの領域でキャンペーンの実施や SNSアカウントを管理するツールなどを提供する会社 2025年3月時点で全社員 63人、エンジニア 31人 エンジニアは自社ツールの開発、キャンペーンの 案件開発を行っています。 X Marketing Partners LINE販促・OMO部門の Technology Partner 青柳康平 バックエンド開発とDB設計が得意 散歩や近所をバイクで走るのが趣味 Copyright ©Unique Vision Company, All Rights Reserved. 2
SNSのAPIラッパーを書いてきました ● ● ● ● ● ● 𝕏 API v1 (twapi-reqwest) 103,638 𝕏 API v2 (twapi-v2) 121,495 Pinterest API (pinterest-api) 2,379 Tiktok Business API(tiktok-business) 9,343 Tiktok API v2(tiktokapi-v2) 14,520 LINE API (lineapi) 1,636 全部cratesとして公開しています。
LINE API 3/13に出したcrateです。 社内で色々なところでLINE APIを利用していましたが、タイムアウトを忘れてたりとか、 バラバラで管理されていて問題になりました。 そこで急遽作成しました。
LINE API すでに何個かcrateがありましたが、自分のやりたいことに沿ってなかったので自作する ことにしました。 他のcrateは型を定義してやり取りできるだけのものでした。 自分は業務に必要な機能をもりこんでAPIを使いたいです。
APIラッパーのコツ(業務で必要な機能) ● ● ● ● ● ● タイムアウト リトライ エクスポーネンシャルバックオフ URLの差し替え reqwestのRequestBuilderをさらけ出す extraフィールド
タイムアウト 意外と忘れがちなのがタイムアウトです。開発中は 順調にレスポンスを返すため失念しがちです。 稼働してしばらくして、プラットフォーム側が不調に なると、APIが返ってこなくなり、タイムアウトが無い とシステムが停止することがあります。
リトライ タイムアウトと同じで、順調だと使わないけど、何かあった時 に必須なのがリトライです。 ちょっとした不調なら何度かのリトライでカバーできます。 ただしリトライで注意が必要なのは、SNSへの投稿などで実 は成功してるけど、レスポンスが届かない場合にリトライで 複数投稿されることがあります。 ちなみにLINEはリトライキーがAPIに用意されているので、 同じリトライキーが設定されているAPIの実行が行われると 409(Conflict)が返ります。
エクスポーネンシャルバックオフ APIが不調な場合に立て続けにリトライすると、プ ラットフォーム側が余計に悪くなる可能性がありま す。 そこでリトライのたびに、リトライ間隔を開けて呼び 出すようにします。 1秒、2秒、4秒、8秒 さらにJitterと呼ばれるランダムな時間を追加して 散らしています。
URL差し替え APIを利用した開発をすると、エラーの場合などの コードを書くことがあります。しかし実際のAPIでエ ラーを起こすのは難しいです。 そこでモックを使います。 Mockitoというcrateはローカルにサーバーを立てて URLを発行してHTTPをモックしてくれます。 URLを差し替えることで、自由にAPIの結果をコント ロールすることができます。
reqwestのRequestBuilderをさらけ出す
ドキュメントにあるリクエストやヘッダーあらかじめ用意することはできますが、ドキュメン
トに無いものは用意できません。
そこでreqwestのRequestBuilderをアクセスできるようにして、利用者が好きなようにリ
クエストやヘッダーを設定できます。
pub fn build(channel_access_token: &str, options: &LineOptions)
-> RequestBuilder {
let url = make_url(URL, options);
let client = reqwest::Client::new();
let mut request_builder = client.get(&url);
request_builder = apply_auth(request_builder, channel_access_token);
request_builder = apply_timeout(request_builder, options);
request_builder
}
extraフィールド
ドキュメントに従ってレスポンス型は用意しています。
しかし、突然変更されたり追加されたりした時にエラーになったりデータを落としたりする
のは避けたいです。
そこでextraフィールドを追加して回収します。
#[derive(Debug, Serialize, Deserialize)]
pub struct ResponseBody {
#[serde(alias = "totalUsage")]
pub total_usage: i64,
#[serde(flatten)]
pub extra: std::collections::HashMap<String, serde_json::Value>,
}
まとめ 仕事でAPIを使う場合は自分でラッパーを書くと、やりたいことができるのでうれしいで す。