タグ付けされた質問 「api-design」

アプリケーションプログラミングインターフェイス(API)の設計では、一般的な目的または公共の使用を目的としたライブラリを作成するためのベストプラクティスについて説明します。

14
バックエンドをAPIとして作成する必要がありますか?
今日、MVCアプリケーションについて熱く議論しました。MVC(ASP.NET)で記述されたWebサイトがあり、通常はビューで何かを実行するパターンに従います->コントローラーを押す->コントローラーがモデルを構築します(データを取得するマネージャーを呼び出し、モデルを構築しますコントローラのメソッド自体)->モデルが表示されます->すすぎと繰り返し。 彼は、私たちのコードが密結合しすぎていると言った。たとえば、デスクトップアプリケーションも必要な場合、既存のコードを使用することはできません。 彼が言った解決策とベストプラクティスは、APIを構築し、APIの上にWebサイトを構築し、デスクトップアプリケーション、モバイルアプリなどを構築することは非常に簡単です。 これは、さまざまな理由で私にとって悪い考えのようです。 とにかく、このプラクティスを議論するかもしれないグーグルで何も見つけられないようです。誰もが長所、短所、なぜそうすべきか、なぜそうすべきではないか、さらに読むべきかについての情報を持っていますか? 悪い考えだと思ういくつかの理由: バックエンドをAPIから実行するにはあまりにも抽象的です。あなたはそれをあまりにも柔軟にしようとしているので、それは管理不能な混乱になります。 MVCに組み込まれているものはすべて、役割や認証など、役に立たないようです。たとえば、[Authorize]属性とセキュリティ。独自にロールする必要があります。 すべてのAPI呼び出しにはセキュリティ情報が添付されている必要があり、トークンシステムなどを開発する必要があります。 プログラムが実行する機能ごとに、完全なAPI呼び出しを記述する必要があります。実装するほとんどすべてのメソッドは、APIから実行する必要があります。すべてのユーザーのGet / Update / Deleteに加えて、ユーザー名の更新、グループへのユーザーの追加など、他の各操作のバリアントがあり、それぞれが個別のAPIコールになります。 APIに関しては、インターフェイスや抽象クラスなどのあらゆる種類のツールが失われます。WCFのようなものには、インターフェイスに対する非常に乏しいサポートがあります。 ユーザーを作成するメソッド、または何らかのタスクを実行するメソッドがあります。50人のユーザーを作成する場合は、50回呼び出すだけです。このメソッドをAPIとして実行することを決定すると、ローカルWebサーバーは名前付きパイプに接続でき、問題はありません-デスクトップクライアントもヒットできますが、突然、ユーザーの一括作成にはインターネット上でAPIを50回ハンマーする必要があります。良くない。したがって、バルクメソッドを作成する必要がありますが、実際にはデスクトップクライアント用に作成するだけです。この方法では、a)統合するものに基づいてAPIを変更する必要があり、直接統合することはできません。b)余分な関数を作成するためにより多くの作業を行う必要があります。 ヤグニ。たとえば、1つのWebアプリケーションと1つのWindowsアプリケーションなど、まったく同じように機能する2つのアプリケーションを作成することを特に計画しているのでなければ、膨大な量の開発作業が必要になります。 エンドツーエンドでステップスルーできない場合、デバッグははるかに困難になります。 多くのやり取りを必要とする独立した操作がたくさんあります。たとえば、いくつかのコードは現在のユーザーを取得し、ユーザーが管理者ロールにあることを確認し、ユーザーが属する会社を取得し、他のメンバーのリストを取得し、それらをすべて送信しますEメール。そのためには、多くのAPI呼び出しが必要になるか、必要な特定のタスクに特注のメソッドを記述する必要があります。特注のメソッドの唯一の利点は速度ですが、欠点は柔軟性に欠けることです。 おそらく、これらの理由のいくつかが私の頭上にあります。 2つの同一のアプリケーションが本当に必要な場合を除き、私には好感が持てますが、それだけの価値はありません。このように構築されたASP.NETアプリケーションを見たことがありません。2つの個別のアプリケーション(APIとコード)を記述し、両方をバージョン管理する必要があります(ユーザーページに新しいフィールドが追加された場合、 dは、APIと消費コードを同時に更新して悪影響を与えないようにするか、堅牢性を維持するために多くの追加作業を行う必要があります)。 編集:いくつかの素晴らしい反応、本当にこれが今何を意味するのか良いアイデアを得るために始めています。それでは、私の質問を拡張するために、このAPI構造に従うようにMVCアプリをどのように構成しますか? たとえば、ユーザーに関する情報を表示するWebサイトがあります。MVCには、次のものがあります。 ビュー-UserViewModelコントローラーを表示する(CS)HTMLページ-GetUser()を呼び出し、GetUserメソッドを持つビューマネージャークラス(APIの一種)に渡すUserViewModelを作成します。 コントローラーはGetUser()を実行しますが、デスクトップアプリも必要です。これは、GetUserが何らかのAPIを介して公開される必要があることを意味します。TCP接続、WCF、またはおそらくRemotingが必要になる場合があります。永続的な接続が不安定なため、RESTfulなモバイルアプリも必要です。 それでは、GetUser()メソッドがあり、コードが実行するWCF Webサービスごとに、各APIを作成しますreturn new UserManager().GetUser()か?そして、同じことを行うMVC 4 Web APIメソッド?MVCコントローラーメソッドでGetUserを直接呼び出し続けていますか? または、3つすべて(Web API RESTサービス)で機能するソリューションを選択し、その上にすべてを構築して、3つすべてのアプリがAPI呼び出し(ローカルコンピューターに対してmvc呼び出し)を行うようにします。 そして、これは単なる理論上の完璧なシナリオですか?特に、RESTfulな方法で操作を行えるように開発する必要がある場合、この方法で開発する際に大きなオーバーヘッドが発生することがあります。これのいくつかは返信で取り上げられていると思います。 編集2:より多くのものを読んだ後、私はそれを説明するかもしれないと思うコメントを下に入れました。この質問は、私が考えるちょっとしたトリックの質問です。APIとしてバックエンドを書くと、すべて(mvcアプリ、デスクトップアプリ、モバイルアプリ)が何かを行うために呼び出す単一のWebサービスがあるべきだと思って混乱しました。 私が思いついた結論は、ビジネスロジックレイヤーが正しく分離されていることを確認することです。コードを見て、すでにこれを行っています。コントローラーはGetUser()マネージャーを呼び出し、それからビューモデルを作成してビューでレンダリングします。実際、ビジネスロジック層は APIです。ただし、デスクトップアプリから呼び出したい場合は、WCFサービスのようなものを記述して、呼び出しを容易にする必要があります。GetUser()コードを含むWCFメソッドを呼び出すだけでもreturn MyBusinessLayer.GetUser()十分です。したがって、APIはビジネスロジックであり、WCF / Web APIなどは、外部アプリケーションに呼び出しを許可するためのほんの一握りのコードです。 そのため、必要なものに応じてビジネスロジックレイヤーをさまざまなAPIでラップする必要があり、他のアプリで実行したい操作ごとにAPIメソッドを記述する必要があるというオーバーヘッドがあります。認証を行う方法を整理しますが、ほとんどの部分で同じです。ビジネスロジックを別のプロジェクト(クラスライブラリ)に固定すれば、おそらく問題はありません! この解釈が正しいことを願っています。それが生成したすべての議論/コメントをありがとう。

4
腐敗防止レイヤーとは何ですか、またどのように使用されますか?
腐敗防止レイヤーの本当の意味を理解しようとしています。私はそれがレガシーコードまたは悪いAPIを移行/回避する方法であることを知っています。私が理解していないのは、それがどのように機能し、何が望ましくない層からきれいに分離するのかということです。 私はいくつかの検索を行いましたが、簡単な例や説明が見つからないため、それを理解し、簡単な例で説明できる人を探しています。私の質問を満足させる答えは、単純なものである必要があり(必ずしも短くはありません)、実装と使用のわかりやすい例を提供する必要があります。 私のユースケースについては、この質問を参照してください。

7
検索はどのようにRESTfulインターフェースに適合しますか?
RESTfulインターフェースを設計する場合、要求タイプのセマンティクスは設計に不可欠であると見なされます。 GET-コレクションの一覧表示または要素の取得 PUT-コレクションまたは要素を置き換えます POST-コレクションまたは要素を作成する DELETE -まあ、ERM、コレクションや要素を削除 ただし、これは「検索」の概念をカバーしていないようです。 たとえば、求人検索サイトをサポートする一連のWebサービスの設計では、次の要件があります。 個々の求人広告を取得する GETへdomain/Job/{id}/ 求人広告を作成 POSTへdomain/Job/ 求人広告の更新 PUT todomain/Job/ 求人広告の削除 DELETEへdomain/Job/ 「Get All Jobs」も簡単です。 GETへdomain/Jobs/ しかし、仕事の「検索」はこの構造にどのように分類されますか? あなたは可能性があり、それは「リストコレクション」のバリエーションの主張として実装します。 GETへdomain/Jobs/ ただし、検索は複雑になる可能性があり、長いGET文字列を生成する検索を作成することは完全に可能です。つまり、ここでSOの質問を参照すると、約2000文字よりも長いGET文字列の使用に問題があります。 例として、ファセット検索があります-「ジョブ」の例を続けます。 「テクノロジー」、「役職」、「規律」、およびフリーテキストキーワード、就業年齢、場所、給与などのファセットでの検索を許可できます。 流動的なユーザーインターフェイスと多数のテクノロジと役職により、検索に多数のファセットの選択肢を含めることが可能です。 この例をジョブではなくCVに微調整すると、さらに多くのファセットがもたらされ、100個のファセットが選択された検索、または50文字の長さ(たとえば役職、大学名、雇用者名)。 そのような状況では、検索データが正しく送信されるようにするために、PUTまたはPOSTを移動することが望ましい場合があります。例えば: POSTへdomain/Jobs/ しかし意味的には、これはコレクションを作成するための命令です。 これを検索の作成として表現することもできます。 POSTへdomain/Jobs/Search/ または(以下のburninggrammaで示唆されているように) POSTへdomain/JobSearch/ 意味的には理にかなっているように思えるかもしれませんが、実際には何も作成しておらず、データを要求しています。 したがって、セマンティック上はGETですが、GETは必要なものをサポートすることを保証されていません。 ですから、質問は-可能な限りRESTfulなデザインを忠実に保ちながら、HTTPの制限内に収まるようにしながら、検索に最適なデザインは何ですか?

14
解決策は可能な限り一般的であるか、可能な限り具体的である必要がありますか?
「タイプ」属性を持つエンティティがあるとします。可能なタイプは20以上あります。 ここで、タイプをA-> Bから変更できるものを実装するように求められます。これは唯一のユースケースです。 したがって、有効なタイプである限り、タイプの任意の変更を許可するものを実装する必要がありますか?または、要件ごとにA-> Bからの変更のみを許可し、B-> AまたはA-> Cなどの他のタイプの変更を拒否する必要がありますか? 両方の長所と短所を見ることができます。一般的な解決策は、将来同様の要件が発生した場合の作業が少なくなることを意味しますが、間違っている可能性が高くなります(ただし、これで発信者を100%制御しますがポイント)。 特定のソリューションではエラーが発生しにくくなりますが、同様の要件が発生した場合、今後さらに作業が必要になります。 優れた開発者は、将来の拡張が容易になるように、変更を予測してシステムを設計する必要があると聞き続けていますが、これは一般的な解決策のように思えますか? 編集: それほど具体的ではない例に詳細を追加する:この場合の「汎用」ソリューションは、「特定」ソリューションよりも作業が少なくて済みます。特定のソリューションでは、古いタイプと新しいタイプの検証が必要です。新しいタイプのみを検証する必要があります。

5
パラメーターが構文的に正しいが、ビジネスルールに違反している場合、HTTP 400(Bad Request)ステータスを返す必要がありますか?
パラメーターとして整数を使用するRESTエンドポイントがあるとします。 /makeWaffles?numberOfWaffles=3 この場合、負の数のワッフルを作ることができないため、この数を正にしたいです(そして、0のワッフルを要求するのは時間の無駄です)。したがって、正の整数を含まない要求を拒否したいと思います。また、最大の整数を超えるリクエストを拒否したい(今はMAX_INTEGERであるとしましょう)。 誰かが非正数のワッフルをリクエストした場合、HTTP 400(Bad Request)ステータスを返すべきですか?私の最初の考えはイエスです:それは私がリクエストを完了するための有効な数字ではありません。ただし、RFCでは、ビジネスルールをスローする理由として言及していません。 400(Bad Request)ステータスコードは、クライアントエラー(たとえば、不正な要求構文、無効な要求メッセージのフレーミング、または不正な要求ルーティング)が原因でサーバーが要求を処理できないか、処理しないことを示します。 ビジネスルールは、これら3つの例のいずれにも該当しません。これは構文的に正しく、適切にフレーム化されており、不正なリクエストルーティングではありません。 パラメータが構文的に正しいが、ビジネスルールに違反している場合、HTTP 400(Bad Request)ステータスを返す必要がありますか?または、返すのに適切なステータスがありますか?
56 api-design  http 

9
外部APIからの予期しない値から保護する必要がありますか?
外部APIから入力を受け取る関数をコーディングしているとしましょうMyAPI。 その外部APIにMyAPIは、a stringまたはa を返すことを示す契約がありnumberます。 それはのようなものから保護することをお勧めしますnull、undefined、booleanそれはのAPIの一部ではないにもかかわらずなど、MyAPI?特に、そのAPIを制御することはできないため、静的型分析などの方法で保証することはできません。 私はロバストネスの原則に関連して考えています。

10
「お住まいの地域ではサービスを利用できません」というエラーのHTTPステータスコードは何ですか?
現在、5つの都市でサービスを提供しています。誰かが他の都市からサービスAPIを呼び出そうとした場合、このエラーをスローしますService not available in your area。 問題は、このエラーに適切なhttpコードは何ですか? 503:サービスを利用できません 403禁止します または、他の何か?
51 api  api-design  http 

14
RESTful APIデザイン。行がない場合、何を返す必要がありますか?
現在、Slim Frameworkを使用してソーシャルネットワーク用のAPIをコーディングしています。私の質問は、json構造に返す行がない場合のベストプラクティスは何ですか? この呼び出し/ v1 / get / moviesがテーブルmovie namesから2行を返すとしましょう: [ {"name": "Ghostbusters"}, {"name": "Indiana Jones"} ] しかし、それから/ v1 / get / booksを呼び出すと、そのテーブルには行がありません。空の構造を返すだけですか? [ ] ...または、メッセージとエラーコードの方が良いでしょうか? [ "errors": { "message": "no matches found", "code": 134 } ] どちらが良い方法ですか?(APIはiOSおよびAndroidアプリで使用されます)ありがとう!

6
多くの小さなリクエストと少数の大きなリクエスト(APIデザイン)
現在、次のような組織でプロジェクトに取り組んでいます。 クライアント -REST APIを介してメインサーバーからデータを取得します。 サーバー -サードパーティAPIを介して他のさまざまなサーバーからデータを要求します サードパーティ API-サーバーにデータを提供する私の制御できないサービス(Reddit、Hackernews、Quoraなど) 議論のために、クライアントが最初に各サードパーティAPIからのアイテムのリストを必要とするとしましょう。このリストからアイテムが選択されます。この時点で、クライアントはアイテムの完全なコンテンツとアイテムへの応答(コメント)を表示する必要があります。私は3つのオプションの間で決定しようとしています: アラカルト このアプローチでは、サーバーに3つのエンドポイントがあります。1つはアイテムのリストを取得し、1つはアイテムのメインコンテンツを取得し、もう1つはアイテムの応答を取得します。 長所:必要以上にリクエストを送信することはありません。リクエストは小さくなければならないので、一般的には高速になります。 短所:私は多くの要求をしなければなりません。リストから項目を選択した後、ユーザーはメインコンテンツを見る前に待たなければならない場合があり、それから応答を見るためにさらに長く待たなければならない場合があります サーバー側キャッシュ このリクエストでは、サーバーを1回呼び出して、すべてのソースのすべてのデータを「フェッチ」します。その後、データはサーバーにキャッシュされます。クライアントは以前と同じRESTエンドポイントを持つことになりますが、サーバーには既にデータがあり、それをクライアントにフィードするだけなので、呼び出しと呼び出しの間にあまり待つ必要はありません。 長所:クライアント側での実装は依然として簡単ですが、遅延の問題はありません 短所:サーバー側が少し複雑で、最初の呼び出しには本当に長い時間がかかる可能性があります。 クライアント側キャッシュ このシナリオは前のシナリオと似ていますが、クライアントがサーバーに対して1回だけ要求を行うという点が異なります。つまり、すべてのデータを提供します。ここから、データを保存して適切に使用するのはクライアントの責任です。 長所:簡単なサーバー実装、最初の呼び出し後は非常に高速 短所:最初の呼び出しは非常に遅く、より複雑なクライアント側の実装になります どちらが最善のアプローチであるのか、あるいは明らかな解決策が欠けているのかもしれません。どんなアドバイスも大歓迎です!

3
PATCHメソッドがべき等でないのはなぜですか?
私はこれについて疑問に思っていました。 フィールドとフィールドを持つuserリソースがあるidとしnameます。フィールドを更新したい場合は、次のようにリソースに対してPATCHリクエストを行うことができます。 PATCH /users/42 {"name": "john doe"} そして、アプリケーションはユーザー42の名前を更新します。 しかし、なぜこのリクエストを繰り返した場合、結果が異なるのでしょうか? よると、RFC 5789 PATCHは安全でもi等でもありません

6
決して公開されることのないコードの防衛的なプログラミング慣行に従うことはどのくらい必要ですか?
私はカードゲームのJava実装を書いているので、ゾーンと呼ぶ特別なタイプのコレクションを作成しました。Javaのコレクションのすべての変更メソッドはサポートされていませんが、ゾーンAPIにmove(Zone, Card)は、指定されたゾーンからそれ自体にカードを移動するメソッドがあります(パッケージプライベートテクニックによって達成されます)。これにより、ゾーンからカードが取り出されず、単に消えることを保証できます。別のゾーンにのみ移動できます。 私の質問は、この種の防御コーディングはどのくらい必要ですか?それは「正しい」ことであり、正しい実践のように感じますが、Zone APIが公共図書館の一部になることは決してありません。それは私だけのためです。したがって、標準のコレクションを使用することでおそらくより効率的になる可能性があるときに、自分からコードを保護しているようなものです。 このゾーンのアイデアをどこまで取り入れるべきですか?誰でも私が書いているクラス、特に実際に公開されないものについては、契約を保存することについてどれだけ考えるべきかについてアドバイスをいただけますか?

3
DOMの何が悪いのですか?
DOMはひどいAPIであると言っている人々(特にCrockford)の声を聞き続けていますが、この声明を正当化するものではありません。ブラウザー間の不整合は別として、DOMがそれほど悪いと考えられる理由は何ですか?

8
java.util.ArrayListでnullを追加できるのはなぜですか?
なぜjava.util.ArrayList追加できるのだろうかnull。に追加nullしたいケースはありますArrayListか? プロジェクトにバグがあり、そこにコードが追加さnullれていて、バグの場所ArrayListを見つけるのが難しいため、この質問をしています。明らかにa NullPointerExceptionがスローされましたが、他のコードが要素にアクセスしようとするまではスローされませんでした。問題は、nullオブジェクトを追加したコードを見つける方法でした。ArrayList要素が追加されているコードで例外をスローすると、もっと簡単になります。

1
null対REST APIレスポンスのキーの欠落[終了]
私のアプリケーションでは、一部のユーザーは姓を教えてくれますが、他のユーザーは教えません。REST APIレスポンスでは、どのボディが優先されます: 「ヌル」値の場合: {"firstName": "Bob", "lastName": null} または、不足しているキー: {"firstName": "Bob"}
40 rest  api-design  json 

11
クエリが存在しないオブジェクトを参照していることを示すために、REST APIは500 Internal Server Errorを返す必要がありますか?
私は、多数のIoTデバイスのデータを処理するサーバーに常駐するREST APIを使用しています。 私のタスクは、APIを使用してサーバーにクエリを実行し、デバイスに関する特定のパフォーマンス情報を収集することです。 ある例では、利用可能なデバイスとそれに対応する識別子のリストを取得し、その後、それらの識別子(GUID)を使用してサーバーに詳細を照会します。 サーバーは500 Internal Server Error、これらのIDのいずれかでクエリを返しています。私のアプリケーションでは、例外がスローされ、エラーの詳細が表示されません。Postmanで応答をより詳しく調べると、サーバーが以下を含む本文でJSONを返していることがわかります。 errorMessage: "This ID does not exist"。 サーバーが最初にIDを提供したという事実は無視してください。これは開発者にとっては別の問題です。 REST API 500 Internal Server Errorは、クエリが存在しないオブジェクトを参照していることを報告するためにを返す必要がありますか?私の考えでは、HTTP応答コードは、APIの内部メカニズムではなく、REST呼び出しのステータスを厳密に参照する必要があります。私が期待する200 OK問題のAPIに独自のだろうエラーと説明を含む応答、と。 REST呼び出しがどのように構成されているかによって、期待に潜在的な違いがあることがわかりました。 これらの例を考慮してください: http://example.com/restapi/deviceinfo?id=123 http://example.com/restapi/device/123/info 前者の場合、デバイスIDはGET変数として渡されます。404または500は、パス(/restapi/deviceinfo)が見つからないか、サーバーエラーになったことを示します。 2番目の場合、デバイスIDはURLの一部です。私はをよりよく理解しますが、404 Not Foundそれでもパスのどの部分が変数とエンドポイントとして解釈されるかに基づいて議論することができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.