この質問は非常に広い領域をカバーしており、単一の回答で問題を詳細にカバーできるとは思えません。私にできることは、私が犯した過ちに基づいていくつかの出発点を提供することです。
独自のAPIの上に構築
する既存のシステムにAPI機能を追加しないでください。そうすることで:
- 追加のテスト負荷が発生します(アプリとAPIの両方を個別にテストする必要があります)
- 全体的なメンテナンスコストが増加します
- 提供したいものよりも品質の低いAPIになります
全体的な目標は、最初にAPIを構築してから、独自のAPIの上にアプリを構築することです。そうすることには、次の利点があります。
- APIのテストは、アプリのテスト中に本質的に実行されます
- 必要なAPIメソッドを追加することを「忘れる」ことはありません
アプリとアプリケーションロジック(API)は論理的に分離されます。方程式の両側で何が行われ、何を担当するかという点で、アプリとアプリケーションロジックは明確に分離されます。これは、開発のガイドに役立ちます。これにより、必要に応じて、アプリとAPIを別のマシンに非常に簡単に配置することもできます。
独自のAPIを使用することは非常に重要なポイントです。APIの設計は最初は最適ではなく、自分で使用することによってのみ、効率的な方法で実際に必要な機能を人々に提供できるようになります。
大まかに次のようなシステムになります。
------------- -------------
| | | |
| Your APP | <= HTTP communication => | Your API |
| | | |
------------- -------------
これにより、さらにいくつかの利点が浮き彫りになります。「Your APP」を他のアプリに置き換えることができるため、顧客は自分に最適な方法で物事を処理するアプリを作成できます。既存のAPIの上に新しいバージョンのアプリを作成することもできます。新しいバージョンの公開Webサイトへの移行ははるかに簡単です。
URLの設計:クラスとメソッドへのマッピング
適切なURLを選択することは、適切なクラスとメソッドの名前を選択することと同じくらい問題です。クラスとそのメソッドからURLを取得することは良いアプローチです。URLとクラス/メソッドの間に適切な相関関係がない場合、長期的には維持するのが難しいことに気付くでしょう。
私は個人的に、次の方法でURLをクラスとメソッドに関連付けることを好みます。
- クラスをトップレベルのディレクトリにマップします
- メソッドをトップレベルディレクトリのサブディレクトリにマップします
例:
APIのURLはhttps://api.camerareadyart.comです。とメソッドを
持つimage
オブジェクトがあります。toColour()
toBlackAndWhite()
これは次のようにマップされる可能性があります。
https://api.camerareadyart.com/image/toColour/
https://api.camerareadyart.com/image/toBlackAndWhite/
同様に、ビットマップからベクターへの変換の場合:
https://api.camerareadyart.com/bitmap/toVector/
応答の設計
誰かがあなたのURLの1つからデータを取得したりPOSTしたりすると、どうなりますか?エラーはどのように処理され、例外はどのように処理されますか?応答はどのような形式を取りますか?
ここで何をすべきかわかりません。個人的には、可能な限りHTTPに近づけてマッピングし、必要な場合にのみこれを超えることを好みます。
たとえば、着信要求が受け入れられて処理されたが、内部でエラーが発生した場合、500ステータス応答を発行します。同様に、特定のAPIメソッドが提供されていない認証を必要とする場合、403を発行する可能性があります。既存のHTTP機能を利用することで、特定のものを再発明する必要がなくなります。
HTTPの既存の側面を使用する
だけでなく、HTTPステータスコードを適切に使用するだけでなく、独自のソリューションを展開する前に、何かを実行するためのHTTPのみの方法を探してください。
応答形式をXMLとJSONのどちらにするかをユーザーが指定したいですか?HTTPAcceptヘッダーを使用します。
リクエストの結果を取得するために、クライアントを別のURLにリダイレクトしたいですか?HTTPロケーションヘッダーを使用します。
HTTPには、やりたいことの多くをすでに処理している多くの機能があります。それらを使用してください!
セキュリティ
ここで取り組むべき一般的な問題は2つあります。ユーザーの認証と、特定のユーザーが実行できるアクションの決定です。
セキュリティ:認証
ユーザーは、リクエストで自分が誰であるかを指定する必要があります。
頭に浮かぶ最初の解決策は、ユーザーがユーザー名とパスワードを指定できるようにすることです。これは、アプリへのアクセスに使用するユーザー名とパスワードと同じである可能性があります。これは一見良い考えのようですが、理想的ではありません。
ユーザーは、ユーザー名とパスワードを自分のアプリに焼き付けることになります。必然的に、1人のユーザーが自分のパスワードを忘れて、自分のアプリに楽しくアクセスできるようにパスワードを変更し、その過程で自分のアプリを壊してしまいます。
より良い選択は、ユーザーが認証トークンを提供することです。これは、ユーザー名とパスワードが1つにまとめられているように、基本的にユーザーに固有の単一の値です。
これにより、ユーザー名とパスワードをAPIへのアクセスから論理的に分離できます。ユーザーは、APIへのアクセスを中断することなく、アプリのユーザー名やパスワードを何度でも変更できます。
また、ユーザーは複数のAPIトークンを持ち、それぞれが異なるレベルのアクセス権を持つことができるため、ユーザーはAPIトークンをサードパーティのサービスに安全に配布できます。
セキュリティ:アクセス制御
外界に関する限り、APIはURLのセットです。各URLは、定義上、一意であり、一意のタスクを実行します。これらの概念に基づいてアクセス制御メカニズムを構築することは、良い出発点です。
トークンがアクセスを許可されているURLのリストをトークンごとに保持することを好みます。特定のトークンを使用してURLにアクセスする場合、アクセスされているURLと、そのトークンがトークンの許可されたURLのリストに含まれているかどうかを確認するのは簡単です。
URLのセットを賢く選択し、各URLが1つの固有のアクションを実行する場合、このプロセスは、取得しようとしている最高レベルのアクセス制御を提供します。
より細かいレベルの制御を行うために、トークンがアクセスを許可されているURLごとに、トークンが使用を許可されているクエリ引数を指定することもできます。