働いている会社で「サービス全体のサーバーサイドの処理をAPIに置きかえよう!」というプロジェクトにアサインされて、初めてAPIをゼロから設計する仕事をすることになって早1ヶ月。初めてだらけで何度も悩みながらAPI設計をし続けていますが、1ヶ月前に比べてだいぶいろんな記事や本にお世話になってきたので、個人的に参考になったなあと思うものたちをまとめておきます。
あと、API設計を進めていく上で個人的にハマったことも書いておきます。後世のAPI設計者が同じような疑問にぶつかった時にハマらないことを願います。(自分の記憶力が🐔レベルなので、メモの意味でもまとめておきます。)
API設計する上で参考になった記事
まずは、初心者の段階で読んでおきたい記事たち。まずはAPI設計はどのように進めていくべきか、どのようなところでハマりやすいのかを知るために記事を読んで大枠を掴むと良いかと思います。
Web APIとは何なのか - Qiita
→そもそもAPIとは何か?なぜAPIを使うべきなのかがまとめられています。まずはAPIを使う目的を理解する上で読んでおきたい。
今さらだけど「Web API: The Good Parts」 を読んだので自分なりにまとめてみる - Qiita
→のちほど紹介する『Web API: The Good Parts』のまとめ記事。まとめ記事なので用語をかいつまむくらいしかできませんが、単語をさらっと頭に入れるつもりで読むと良さそう。
翻訳: WebAPI 設計のベストプラクティス - Qiita
→文章が長めですが、API設計時にどう設計するか悩んでハマりやすいポイントがまとめられていてとても参考になります。そもそもAPIの設計でどのような点に注意すればいいのかを知ることができる。
綺麗なAPI速習会 - Qiita
→API設計で悩むバージョン管理やページングの実装、共通処理の共通化(BFF(Backends for Frontends)を採用するべきか?)に関してまとめて書かれていて、参考になります。
【連載】Swagger入門 - 初めてのAPI仕様管理講座 [1] Swaggerとは|開発ソフトウェア|IT製品の事例・解説記事
→API仕様管理にはSwaggerが向いてるよ!っていう記事。フロントエンドとサーバーサイドはAPIのリクエスト・レスポンスをもとに会話することが多いですが、その仕様をドキュメントで管理しようとすると保守するコストが大きくて徐々に古くなって誰も仕様書をメンテしようとしなくなって、数年後には、「仕様はソースコードを読まないとわからない...。」という状況になってしまいがち。そんな仕様の保守コストを減らすために、コードからAPIドキュメントを自動生成してくれるSwaggerは、絶対導入検討すべきだと思います。
API設計する上で参考になった本・動画
インターネット上の記事はパッと概念や単語を拾うなら効率がいいですが、体系的に知識を学ぶならやはり本が一番だと思います。中でも以下に挙げる3冊は必ず読んでおくべきかと思います。
そもそもなぜWebはここまで広く浸透したのか、HTTPの仕組みや基本思想はどのようなものなのか、Webの仕組みはどうなっているのか、RESTの考え方はSOAPなどと比較して何が優れているのかを知れる。Webの基礎を学ぶ意味でも読んでおくべし。
API設計において気をつけるべき要点、悩みがちな箇所とそこでどう選択するべきか、有名WebサービスのAPIはどうなっているのかが分かりやすく説明されている名著。かつオライリーにしては薄めの本でサクッと読みやすい。API設計をするなら必ず読んでおべきかと。
マイクロサービスを設計する上で注意するべきことは何か、設計した後に実際に運用していく上で何を意識するべきか、設計の時に何を気をつけないといけないのかが具体的に書かれている名著。🐔の自分には、1度読んだだけでは全部理解できなかった。何度も読みたい本。
REST API Design, Development & Management
REST APIの設計方法、REST APIのセキュリティの仕組み、Swaggerの使い方や、APIを外部公開するときに注意するべき点など、REST APIに関して網羅的に学ぶことができるコースです。
英語なのでわかりにくい箇所はGoogle翻訳に頼る必要もありますが、API設計時に考えるべき観点として有益な情報が多かったです。
REST API Design, Development & Management
API設計する上で参考になったAPI
大手WebサービスのAPI設計から学べることは多々あります。『Web API: The Good Parts』でも紹介されていましたが、実際にAPIのドキュメントを読んでみると発見が多いのでぜひ読んでみてください。
ConfluenceのPaging処理
→Paging処理をどのように設計するのかという点で参考になりました。
FacebookのPaging
→Facebookはnextとprevで前後のURLをレスポンスに含んでいる形式。フロントエンドに優しい設計ですね。
TwitterのPaging
→Twitterのページング処理は、max_id、since_idなどをリクエストに含ませて、どこから検索するかを指定することができる形式。
Google Cloudのレスポンスのステータスコード
→レスポンスのステータスコードの何番をどのタイミングで使うべきなのかを検討する時に役に立ちました。
InstagramのAPI設計
→Envelope形式で、ステータスコードをレスポンスボディに持たせるような設計にしているInstagram。この形式は採用しませんでしたが、まあそういう考え方もあるよねと参考になります。
さいごに、個人的にAPI設計でハマったとこに関してまとめておきます。
API設計する上で個人的にハマったこと
API仕様の保守・運用方法の統一
当初はAPI仕様をサーバーサイドエンジニアがドキュメントに書いて、そのドキュメントをもとにAPIのリクエスト・レスポンスをフロントエンドエンジニアに確認してもらい、足りないレスポンスはないかをコミュニケーションを取るようにしていました。最初の頃はその方法でコミュニケーションも問題なく進んでいましたが、開発が進んでいくうちに徐々にAPIの仕様とコードの間に乖離が生まれるようになっていき、最新のコードの状態がドキュメントに反映されていない状態になってしまってうフロントエンドエンジニアがAPIのリクエストを知ることができない状態が生まれてしまいました。この状態は健全ではないということでSwaggerを導入し、Swaggerを起動すればコードに書かれたリクエスト・レスポンスの値が誰のPCでも確認できる状態にしました。
これによって仕様の保守コストが下がったので、最初からSwaggerのような自動API仕様出力フレームワークの導入を検討しておくべきだったなあと悔やみました。
テスト方針の明確化
当初はテスト方針を明確に定めておらず、「APIのロジック部分には単体テストを書こうね!」くらいの認識しかありませんでした。結果として、APIアクセスのバリデーションに対してのテストとフロントエンド側のUIテストがほとんど書かれていない状態になってしまい、毎回画面上で操作して手動でテストを実施する運用になってしまいました。
プロジェクト開始当初からどこまで自動テストにして、どこからは手動のテストにするのかを明確にしてルール化して、そのテスト方針に従ってなければプルリクエストをレビューNGにするなどの運用をしておくべきでしたね。
プロジェクトメンバー全員のアーキテクチャの理解不足
プロジェクトの発足当初から関わっていた技術力の高いメンバーがアーキテクチャの設計部分を担っていたおかげで全体のアーキテクチャの設計は迅速に進みましたが、その後に加入したプロジェクトメンバーへのアーキテクチャの説明を怠っていたため、全メンバーがどのレイヤーでログイン情報を取得するのか、どのレイヤーでDBアクセスをするのか、Facade内でDBアクセスをしてもいいのかなど理解できておらず、レビューされて初めて問題に気づいて大幅に手戻りが発生する事態となりました。
事前に新規加入者がアーキテクチャと各レイヤーでの役割の違い、依存関係、手本となるようなAPIがまとまった手順書のようなものを用意しておき、まずはそれを読んでもらうことを徹底していれば少しは解決できたのかなと思います。
フロントエンドとサーバーサイドの役割の明確化
フロントエンドとサーバーサイドの役割分担はどうするのか?を相互に話し合っていなかったため、個別のAPIの話をする段階で「フロント側でコード値と具体的な値の対応関係を保持しておいて、APIのレスポンスの持っているコード値を元にフロント側で計算するのはしんどい。PCやアプリのそれぞれのクライアントサイドで同じような処理をデバイスごとに書かないといけなくなるし...。とはいってもすでにAPI結構作っているし、今までのAPIを同様のルールで全部書き直すのはサーバーサイドとしてはしんどい...。」となってしまいました。
事前に具体的な値の取得などはサーバーサイドのAPIの役割にし、フロントエンドの役割はAPIで返されたものを表示するだけ。という役割分けなどの話をもう少し早めにできていればよかったなと。個別のAPIを一つでも作ってみて、そのAPIをもとにフロントエンドとサーバーサイドエンジニアで集まって話し合ってみれば、そのAPIで問題がないのか、フロントエンド側で画面の実装イメージは湧くか、サーバーサイドの処理は高負荷にならないか、など具体的に検討できると思うので、先に1つでもAPIを作り切って、それをもとにAPIとフロントエンドの役割分担が明確になってから他のAPIをゴリゴリ開発していくのがよいなと。
既存仕様と新規API仕様の共通化・刷新方針
これは既存の仕様で使われている変数名やデータベース名と、新規のAPIのパラメータ名を共通化させるべきかという問題や、既存の処理でPCとアプリで同じ機能なのに別々のデータの持たせ方をしている時に、新規のAPIではPCもアプリも同様の処理をさせたい時にどのように共通化させるのかという問題など、過去の遺産との向き合い方に関して悩むことが多かったです。
さらに、過去の遺産(特に、「あれ?なんでここってこうなってんの?」となる部分)は見えない背景があってそうなっていることが多いので、うかつに変更を加えてしまうと今まで神技的に実現されていた秘伝のコードが千切れてしまって思わぬところで不具合が発生してしまったりします。しかも、単体テストも十分に書かれていないからテストの失敗によって不具合を検知することができない...。これは過去のプロダクト開発の背景を知らないメンバーからするとどうしようもない問題なので、昔からいるメンバーにレビューをもらうこと、数年後に同じような状況に陥らないために新規のコードでは単体テスト(特にサービスとして肝となる部分にはE2Eテストも)を書くことを徹底することが大事ですね。
まとめ
以上、「初めてWeb API設計をする前に読みたい記事・本・API実例と個人的にハマったこと」でした!
みなさんもAPI設計するときには先人たちのありがたい失敗談をどんどん聞いて同じドツボにはまらないようにしましょう〜!
では!