Web API Advent Calendar 2021の13日目の記事です!
今年、新規に一から自社のプロダクトを設計、開発するチャンスがあり、どんな感じで進めたかを記録しておきたいと思います。
具体的な例があったほうが面白いかなと思い、出せそうなものは記載しました。
プロダクトはマルチテナントな建設向けのIoTプラットフォームです。
テナントごとに持っている現場単位で利用者やモノの管理を行います。
全体を通して気をつけたのは2点です。
- ドキュメントやコードを拡張、メンテナンスしやすいこと
- APIのクライアントの実装者が一般的なAPIのお作法に沿って使える。使いやすい、デバッグしやすいこと
アーキテクチャ
フロントエンドはSPAやモバイルアプリなので、バックエンドの機能はすべてAPIになっています。
実行基盤としてはAWS ECS。言語・フレームワークはTypeScriptでExpressを使っています。
サービスの設計
DDDでやりました。ドメインモデルを書いてスタートしたのですが、プロジェクトが進んでいった後も、ドメインモデルに立ち戻って会話したり、新しく入った人が概要を理解するのに良かったと思います。
単純なAPIは良いのですが、いくつかの複雑になりそうなAPIはこんな感じの構成でやろうね、という認識合わせのためにモデリングしました。中間資料的な位置づけでメンテはしていかないつもりです。
API Spec
API仕様はOpenAPIで書きました。
エンジニアだけじゃなくて、最近転職してきたばかりのコンサルロールの人にもOpenAPIで書いてもらいました。最初はStoplight Studioの癖や、使いやすいAPIの定義みたいなところで認識合わせが必要でしたが、結構うまくいったように思います。
今は内部的にしか公開していませんが、APIを社外の方からも使っていただけるように公開していきたいと考えています。
RESTfulにした
原則としてAPIはRESTfulの考え方に沿ってデザインしました。
画面のワイヤーデザインと、ドメインモデルを見ながらリソースを定義していきました。
- 例
/sites/{siteId}/elements/{elementId}
RESTfulにしなかったもの
検討した上で一部例外的にRESTfulにしなかった例です。
- コマンドっぽいやつ
- 現場の施工開始
POST /sites/{siteId}/start
- 現場の施工完了
POST /sites/{siteId}/complete
- 現場の更新でstatus属性を更新というやりかたもあったのですが、開始、完了に伴うドメインルールがいろいろあったので独立させました
- 現場の施工開始
- バルクアップデート(一括登録・更新)みたいなやつ
- 画面には複数件のフォームがあって、APIには配列で渡して一部は新規登録、一部は更新処理を行いたいケースです。新規と更新が混じるので、POSTとPUTで分けるようなことはできず、全部POSTでやりました
- 削除だけは該当行のリソースIDを指定してDELETEメソッドで実装しました。んーどうなんだろう。トランザクションとか考えると、バルクアップデートの一部に入れたほうが良かったのだろうか。
エラーの返し方
フロントエンドや、API連携先のクライアントアプリケーションが、どのAPIを使っても共通のルールに沿って例外処理を実装できるように心がけました。
- バックエンドが原因のエラー
- HTTPステータスコード 500
- リクエストに起因するエラー
- HTTPステータスコード 400系
- エンドユーザーにメッセージを表示する際に使用するエラーコードを返す
- APIのクライアントの実装者がデバッグできるように、エラーの内容を文章で返す
認証・認可
- 認証はAWS Cognitoで行っています
- テナント単位の認可はCognitoの属性にテナントの情報をもたせて、ミドルウェア的な領域でアクセスしようとしている先に、権限があるのかをチェックしています。
当然自分一人で上記をやったわけではなく、チームで議論しながら進めました。特に、久光さんが中心的に設計されたところも多いことを付け加えさせていただきます!
以上です。質問やアドバイスなど大歓迎です。