1. APIの設計・開発
エクメルンのフロントエンドはReactを使ったSPA(Single Page Application)で作られていて、バックエンドのAPI部分はRailsで作られています。非常にタイトなスケジュールでしたが、フロントとサーバーサイドは疎な関係としてすべてAPI経由で情報を取得するよう構築したので、開発・テストしやすかったです。Rails5ではAPIモード、Rails 5.1ではReactやwebpackなどが組み込まれ、世の中的にこのようなアプリケーション構成が標準化されつつあると感じています。
1.1. 参考にした書籍
「Web API: The Good Parts」水野 貴明氏
Web APIの設計や開発や運用において、留意すべきことを簡潔にまとめた本。
1.2. 設計と開発
APIの設計は画面を意識しすぎず、オブジェクトを表す塊を返す設計を心がけるバックエンドの設計がURIに反映されていないこと
(APIは今後公開されることを考えると、画面に依存したデータを返さない)
"設計の美しいWeb APIは使いやすい
設計の美しいWeb APIは変更しやすい
設計の美しいWeb APIは頑強である
設計の美しいWeb APIは恥ずかしくない”
WebAPI The Good Partsより
これらを実現するためにも世の中のWebAPIを調べ、デファクトスタンダードに従いました。本書では著名な企業(Twitter, Google, Facebookなど)のAPIの仕様を比較しています。デファクトスタンダードに従うことで、他のAPIを利用してきた開発者がこのAPIを見たときにも容易に利用方法が推測し開発が行えるようになります。
1.2.1. URI設計
- 覚え易く、どんな機能を持つURIなのかひと目で分かるAPIを目指す
- RestfulなURL設計となっていること
- /users ユーザの一覧取得
- /users/1 ユーザの詳細情報取得
- /me 本人に関する情報を取得
- 互換性を持たせるために、エンドポイントにはバージョンを含める
- example.com/api/v2/
- バージョンは railsの場合namespaceで定義 namespace :v2
1.2.2. データ形式
- 形式はJSON
- データはフラットではなく、入れ子構造を採用
- Json出力にはActiveModelSerializersを利用
- モデルの属性を指定すると、Jsonに書き出せる
- エスケープを適切に行なってくれる
- 入れ子を定義することも可能
- 大まかなエラーの種別はステータスコードで表現
- ステータスコード:400, 詳細:「メールアドレスまたはパスワードが間違っています。」
- ステータスコード:429, 詳細:「ログイン回数の制限を超えました。1 時間後に再度試してください。」
1.2.3. セキュリティ
- 通信にはHTTPSを利用
- 悪意あるアクセスを防げる仕組み
- ログイン試行 アプリケーションでログイン試行回数を設けて、一定の試行回数を超えるとブロックする
- 大量アクセス対策 rack-attack
- WAFを使ったBlock
- パラメータの改ざんにも配慮
- 購買金額なのど情報はユーザからは受け取らず内部で計算することで不正操作を防止
- ユーザの権限フラグをAPI経由では直接変更できなくするなど
- 適切なCORSの設定
1.2.4. 開発とテスト
1.2.5. その他所感
- APIの定義には試行錯誤は向かない。はじめにきっちり決めておく。
- Railsの場合、モデル名がルーティングに大きく影響するので、オブジェクトを表すわかりやすい名詞を選ぶと良い
- 関連のあるモデルを表現する際にはネストしたURL設計とすること
- 仕様が決まれば、フロントエンド、バックエンドそれぞれ実装を進める
- バックエンドはrailsのroutes.rbを記述していきrake routesでAPIの一覧が仕様を満たしているか確認
- コントローラに対するコード記述はScaffoldで生成されたコードから乖離しない程度の記述量でいく
- Actionはなるべく追加せず、1コントローラにCRUD1セットが収まるように実装
- 不要なアクションはroutes.rbでブロック
- 定義を1つずつ書かず、namespace、resources、resourceを用いればキレイに記述できる
- assert_response_schemaでJSONスキーマを利用したJSONの妥当性確認が可能
- API開発は、Postmanを使った動作確認が便利
- フロントエンドは、モックを使って開発
- フロントとバックエンドの結合はいきなり行うのではなく、バックエンドが出来上がり次第順次、確認を行える環境を用意しておく
- Herokuに最新の動作するバックエンドがデプロイされる仕組みは大変有効だった
- APIの定義には試行錯誤は向かない。はじめにきっちり決めておく。