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

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

1
CでのC ++テンプレートタイプAPIの慣用的なラッピング
C関数でデータストア(Hazelcast)へのアクセスを提供するC ++ APIのラップに取り組んでいるため、データストアはCのみのコードからもアクセスできます。 Mapデータ構造用のHazelcast C ++ APIは次のようになります。 auto map = hazelcastClient->client->getMap<int, string>(mapName); map.put(key, value); とテンプレートのテンプレートタイプを使用keyしvalueます。Cには利用可能なテンプレートがないため、getMap<T, U>メソッドの特殊化ごとにラッパー関数を作成することを考えました。つまり、Cタイプごとに。私があることを承知しているが、signedおよびunsignedCタイプのバージョンは、私だけをサポートするAPIを制限して大丈夫だよint、double、float、char *のためにkeyとvalue。 そこで、すべての組み合わせを自動生成する小さなスクリプトを書きました。エクスポートされた関数は次のようになります。 int Hazelcast_Map_put_int_string( Hazelcast_Client_t *hazelcastClient, const char *mapName, int key, char *value, char** errptr ); int Hazelcast_Map_put_int_int( Hazelcast_Client_t *hazelcastClient, const char *mapName, int key, int value, char** errptr ); ... 機能の生成get、set、containsすべての可能な組み合わせとkeyし、value種類は非常に多くのコードの量を増加させ、そして、私はコードを生成することは良いアイデアだと思いますが、それはコード生成インフラのいくつかの種類を作成することによって、追加の複雑さを追加します。 私が想像できるもう1つのアイデアは、次のようなCの一般的な関数の1つです。 int …
9 c++  c  api-design 

3
CRUD API:更新するフィールドをどのように指定しますか?
ある種のデータベースに永続化されているある種のデータ構造があるとします。簡単にするために、このデータ構造を呼びましょうPerson。これで、他のアプリケーションがを作成、読み取り、更新、および削除できるようにするCRUD APIを設計する必要がありますPerson。簡単にするために、このAPIが何らかのWebサービスを介してアクセスされると仮定します。 CRUDのC、R、Dパーツのデザインはシンプルです。私はC#のような関数表記を使用します-実装はSOAP、REST / JSON、またはその他の可能性があります。 class Person { string Name; DateTime? DateOfBirth; ... } Identifier CreatePerson(Person); Person GetPerson(Identifier); void DeletePerson(Identifier); アップデートはどうですか?自然なことは void UpdatePerson(Identifier, Person); しかし、どのフィールドを更新するかをどのように指定しますPersonか? 私が思いつくことができる解決策: 常に完全な Personを渡すように要求することができます。つまり、クライアントは次のようにして生年月日を更新します。 p = GetPerson(id); p.DateOfBirth = ...; UpdatePerson(id, p); ただし、そのためには、GetとUpdateの間にトランザクションの整合性またはロックが必要になります。そうしないと、他のクライアントによって並行して行われた他の変更を上書きする可能性があります。これにより、APIがさらに複雑になります。さらに、次の疑似コード(JSONをサポートするクライアント言語を想定)であるため、エラーが発生しやすくなります。 UpdatePerson(id, { "DateOfBirth": "2015-01-01" }); -これは正しいように見えます-DateOfBirthを変更するだけでなく、他のすべてのフィールドをnullにリセットします。 であるすべてのフィールドを無視できますnull。しかし、それを変更しないこと DateOfBirthと、意図的にnullに変更することの違いをどのように作成しますか? 署名をに変更しますvoid UpdatePerson(Identifier, Person, ListOfFieldNamesToUpdate)。 署名をに変更しますvoid …

2
イベントリスナーは弱い参照で保持されるべきですか?
通常、イベントリスナーは、それらを登録したオブジェクトよりも長く存続するべきではありません。 それは、イベントリスナーがデフォルトで弱参照によって保持されるべきであることを意味しますか(オブジェクトリスナーが登録されている弱コレクションに格納されます)? リスナーがその作成者よりも長生きする必要がある有効なケースはありますか? それとも、そのような状況は間違いであり、許可されるべきではないのですか?

1
バージョン管理API
APIベースでサポートされている大規模なプロジェクトがあるとします。このプロジェクトには、エンドユーザーが使用できるパブリックAPIも含まれています。 場合によっては、プロジェクトをサポートするAPIベースに変更を加える必要があります。たとえば、APIの変更や新しいメソッドを必要とする機能を追加したり、APIとの間でやり取りされるオブジェクトの1つまたはオブジェクトの1つの形式を変更したりする必要がある機能を追加する必要があります。 パブリックAPIでこれらのオブジェクトも使用していると仮定すると、パブリックオブジェクトもこれを実行するたびに変更されます。これは、クライアントが解析コードを機能させるために同一のままであるAPIオブジェクトに依存する可能性があるため望ましくありません。(咳C ++ WSDLクライアント...) したがって、解決策の1つは、APIをバージョン管理することです。しかし、APIの "バージョン"と言うと、これは、変更されたメソッドシグネチャごとに重複したメソッド呼び出しを提供するだけでなく、APIオブジェクトをバージョン化することも意味しているように思えます。したがって、APIのバージョンごとにプレーンな古いclrオブジェクトを作成しますが、これもまた望ましくないようです。そして、たとえこれを行っても、膨大な量の重複したコードが作成されることになるため、各オブジェクトを最初から構築することはありません。むしろ、APIはベースAPIに使用しているプラ​​イベートオブジェクトを拡張する可能性が高いですが、追加のプロパティが想定されていないときにパブリックAPIでも使用できるため、同じ問題が発生します。 では、この状況に通常適用される正気とは何でしょうか?Git for Windowsなどの多くのパブリックサービスがバージョン管理されたAPIを維持していることは知っていますが、バージョン管理されたさまざまなメソッドや入出力オブジェクトをカバーする膨大な量の重複コードなしでこれをサポートするアーキテクチャを想像するのに苦労しています。 セマンティックバージョニングなどのプロセスは、パブリックAPIのブレークが発生したときに何らかの健全性を提供しようとすることを知っています。問題は、オブジェクトが分離されていない場合、多くの変更またはほとんどの変更でパブリックAPIを解除する必要があるように見えることですが、コードを複製せずにそれを行うには良い方法がありません。

2
サブパッケージで定義されたインターフェースの実装はアンチパターンですか?
私が以下を持っているとしましょう: package me.my.pkg; public interface Something { /* ... couple of methods go here ... */ } そして: package me.my; import me.my.pkg.Something; public class SomeClass implements Something { /* ... implementation of Something goes here ... */ /* ... some more method implementations go here too ... */ } つまり、インターフェースを実装するクラスは、実装するインターフェースよりもパッケージ階層のルートの近くにありますが、どちらも同じパッケージ階層に属しています。 …

5
関数ベースのRESTful APIの設計
私と友達の間で議論を解決してください。 現在、製品APIを設計しています。製品エンティティは次のようになります { "Id": "", "ProductName": "", "StockQuantity": 0 } 製品の販売はサードパーティが処理し、StockQuantityフィールドを減らすことができるように購入数量を通知する義務があります。 私のアプローチ: PUT /api/Product/{Id}/ --data { "StockQuantity": "{NewStockQuantity}" } サードパーティは、製品のクエリ、現在のStockQuantity購入数量に基づく計算、およびPUT新しい値でのリクエストの送信を担当します。 私の友人はサードパーティに計算を望まない。彼のアプローチ PUT /api/Product/{Id}/DecreaseStock --data { "PurchasedQuantity": "{PurchasedQuantity}" } したがって、計算を行って、 StockQuantity 私は関数ベースのエンドポイントを作成したくありません、そして彼は計算を行うためにサードパーティを信頼したくありません。 この問題に取り組むための正しい方法は何でしょうか?

2
マイクロサービスアーキテクチャにおける多くのアプリケーションのAPIエンドポイントの維持と文書化
マイクロサービスを使用する上での最大の問題点の1つは、APIが十分に文書化され、APIがダウンストリームアプリケーションに影響を与えずに動作を変更しないことを確認することです。この問題は、相互に依存し合うサービスが多数ある場合に増幅されます。多分その時点であなたは間違ったマイクロサービスをやっていますが、私は余談です。 異なるチームが所有する20のマイクロサービスを継承していて、どのアプリケーションが他のどのアプリケーションのAPIエンドポイントを使用するかについての明確なドキュメントがないとします。これを文書化する規定された方法はありますか?最初に、各アプリケーションのエンドポイントを分析してデータベーステーブルに追加し、多対多テーブル(ほとんどすべてがRailsアプリケーションです)で各アプリケーションとアプリケーションのルート間にFK関係を作成することを考えました。しかし、これがこれを処理するための良い方法であるかどうか、または私はここで車輪を再発明しているかどうかわかりません。 振り返ってみると、マイクロサービスをゼロから始めている場合、これはアプリケーションの相互作用を文書化するのにそれほど悪くない方法かもしれません。これにより、データベースを使用して単一の信頼できる情報源が維持され、エンドポイントへの変更は、データベースの変更と連動してアプリケーションで実行されます。考え?

5
Rest APIの設計-IDまたはリテラル文字列を操作しますか?
RESTful Webサービスを設計するとき、サーバー間でやり取りされる値の文字列のIDを機能するようにAPIを設計する必要がありますか? 次に例を示します。ステータスと性別の属性を持つ従業員リソースがあるとします。データベースのステータスと性別、および個別のテーブル、つまり個別のドメインオブジェクトで、それぞれが独自の識別子を持ちます。 クライアントのリクエスト/ employee / 1としましょう。サーバーが次のようなものを返す可能性があります... ケース1: { "id": 1, "firstName": "Jane", "lastName": "Doe", "active": true, "gender": { "id": 1, "gender": "FEMALE" }, "status": { "id": 3, "status": "FULL_TIME" } } ケース2: { "id": 1, "firstName": "Jane", "lastName": "Doe", "active": true, "gender": "FEMALE", "status": "FULL_TIME" } ケース3: { "id": …
8 rest  api-design  json 

1
本REST vs Too many Requests
偽のREST APIを非難する彼自身の記事に関するロイフィールディングのコメントから: 真にRESTfulなAPIはハイパーテキストのように見えます。すべてのアドレス可能な情報単位は、明示的に(たとえば、リンクとID属性)または暗黙的に(たとえば、メディアタイプの定義と表現構造から派生)のいずれかでアドレスを伝達します。クエリ結果は、オブジェクト表現の配列ではなく、要約情報を含むリンクのリストで表されます(クエリはリソースの識別の代わりにはなりません)。 これは、たとえば、最近ログインした100人のユーザーのリストをクエリして、その名前と電子メールを表示する必要がある場合、最初GETに結果のリストをクエリする必要があることを意味します。リンク要素のリストであり、各リンクオブジェクトにはユーザーリソースのURIが含まれます。結果を表示するために必要なデータを実際に取得する前に、さらに 100のGETリクエスト(ユーザーリソースごとに1つ)を行う必要があります。 それは信じられないほど非効率的です。1つまたは2つの要求で必要なデータを取得するための本当にRESTfulな方法は他にありませんか?
8 rest  api  api-design 

4
依存関係の逆転によりAPIが拡張され、不要なテストが発生する
この質問は数日間私を悩ませてきました、そしてそれはいくつかの実践が互いに矛盾しているように感じます。 例 反復1 public class FooDao : IFooDao { private IFooConnection fooConnection; private IBarConnection barConnection; public FooDao(IFooConnection fooConnection, IBarConnection barConnection) { this.fooConnection = fooConnection; this.barConnection = barConnection; } public Foo GetFoo(int id) { Foo foo = fooConection.get(id); Bar bar = barConnection.get(foo); foo.bar = bar; return foo; } } これをテストするとき、IFooConnectionとIBarConnectionを偽造し、FooDaoをインスタンス化するときに依存性注入(DI)を使用します。 機能を変更せずに実装を変更できます。 …

3
重大なAPIの変更:ライブラリユーザーが簡単に移行できるようにするにはどうすればよいですか?
以前は、@DeprecatedAPIバージョンにアノテーションを追加する標準的な方法を使用していましたが、今後のバージョンでは削除されます。 現在、ライブラリのメジャーバージョンを準備しています。多くのAPIパーツが削除され、名前が変更されています。 既存のユーザーが簡単に移行できるようにするには、新しいライブラリバージョンを古いバージョンと並べて使用できると便利な場合があります。 メリット バージョン間の動的切り替えを実装できます 新しいバージョンでバグが見つかった場合、アプリケーションは前のバージョンにフォールバックできます(ベータ段階で役立ちます) これを行うために、私は単純に新しいパッケージに新しいライブラリのバージョンを移動することができcom.mycompany.libraryへcom.mycompany.library.v2 これは一般的な方法ですか、それともこのようなJavaライブラリの並列使用について他の推奨事項がありますか? バックグラウンド: ライブラリはシンプルなドキュメントコンバーターです。そのため、convert(in、out)メソッドのほかに、多くの構成プロパティといくつかのイベントハンドラーがあります。サイドバイサイドの使用法を提供する場合、コンシューマーはそれらを動的にインスタンス化して構成できます。 if (useVersion2) { com.mycompany.library.v2.Converter c = new com.mycompany.library.v2.Converter(); // configure and run c.setOption(...); c.convert(in, out); } else { com.mycompany.library.Converter c = new com.mycompany.library.Converter(); // configure and run c.setOption(...); c.convert(in, out); } (質問は/programming/37192945/から移動しました)

1
ページング戦略:ページトークンとスキップ/開始インデックス
多くのアイテムを含む結果のページ間をユーザーが移動できるようにするために、ページトークンを使用する新しいAPIがますます増えていることを確認しています。ただし、APIデザイナーの観点からは、ユーザーがスキップしたいアイテムの数を指定できるようにする場合と比較して、トークンを使用する利点が何であるかは明確ではありません。 だからここに私の質問があります: 開始インデックスよりもページトークンを使用する利点は何ですか? 大まかに言えば、一般的なページトークンの実装では、どのようにしてページを追跡するのでしょうか。すべての結果をキャッシュすると、かなり非効率になります。ある種のハッシュを使用できると思いますが、結果を再構築するために何がハッシュされるのかわかりません。 ありがとうございました

2
ORMで複雑な計算フィールドを処理する方法
私たちのAPIには、計算された値を持つデータベースから取得した後に(いわば)「装飾」する必要があるいくつかの中心的なデータ型があります。データベースは、CakePHP 3データベースレイヤーから大きく影響を受けたテーブル/エンティティダイナミックに従うORMを介してアクセスされます。テーブルオブジェクトは、データベースと、モデルオブジェクトインスタンスとして行を取り込んで渡すアプリケーションとの間の仲介として使用されます。したがって、データベースからデータを取得してそれらの行を返すだけでなく、返されたデータを実際に使用する前に前処理する必要があります。ここに私が何を意味するかをよりよく説明するために出てきたいくつかのユースケースがあります: オブジェクトには数値があり、ユーザーフレンドリーなラベルに変換されます(通常、これは純粋にクライアントに保持するロジックですが、ビジネスセキュリティ上の理由から、このデータの一部はサーバーにのみ保持する必要があります。エッジケース) オブジェクトには、最後に追加された評価から取得された関連する評価値が必要です このような計算値と保存された値の組み合わせに基づいて、複雑なスケジュールオブジェクトが構築されます 単独では、これらのいずれもmap()、返された結果セットに対する単純な操作で実際にかなり簡単に実行できます。同じことが複数の計算値が必要な場合にも当てはまります。必要に応じて、より多くのマップ操作を実行して、それらのフィールドを計算および追加できます。 とはいえ、このアプローチには2つの大きな欠点があります。 これは、これらの計算された値を操作するすべての場所で後処理の追加の手順を実行する必要があることを意味します。これは特にDRYではありません。 これらの変換の一部は、最初に実行される他の変換に依存しています。それ以外の場合は、操作できるデータがありません。 両方を処理するために、このコードをORMに移動し、ORMを変更して、インターフェイスが(外部で)データベース列を処理するのと同じ方法で計算された仮想フィールドにアクセスできるようにするのが最善のアプローチであると考えていました。内部的には、これらの仮想フィールドを変換関数にマップし、潜在的に必要な依存関係変換を内部的に決定して、2番目の問題を解決することができます。 (余談ですが、これにより、単純なハッシュではなく、返された行が実際のオブジェクトである必要がなくなるかどうか疑問に思っています。現在、各行は、フィールドデータセットが設定された新しいオブジェクトをインスタンス化しますが、すべての計算またはデータの変更はモデルの外に移動され、オブジェクトはプロパティのバッグになります-本質的に、それ自体の内部ロジックを持たないハッシュマップです。これは実際には悪いことではないかもしれません)

2
REST APIリソースをビジネスドメインに基づいた領域に分割する
いくつかの関連ドメインをカバーする主要なアプリケーションREST APIでは、リソースが属するビジネスドメインに基づいてリソースを「エリア」に分割する方が理にかなっていますか、それとも単一のモデルを維持する方が良いですか? たとえば、「販売」と「在庫」のサブドメインがあります。システムのユーザーは通常、一度に1つのドメインのみを考慮しますが、例外が発生する可能性もあります。両方のドメインに存在する「アイテム」の概念があるため、「アイテム」リソースを2つの異なる方法で実装できます。 各ドメインの概念を表すさまざまなリソースがあり、各リソースは関連データのみを保持しています。 / sales / items /:id / inventory / items /:id すべてのコンテキストで使用されるすべてのデータを含む単一のリソースがあります。 / items /:id ドメインの1つだけに属するリソースもたくさんあります。 「地域」の長所 単一ドメインのみに関心があるユーザー向けのAPIを理解しやすくする リソースの実装が簡単(一度に読み取る/更新する項目が少ない) 特定のドメインごとにリソースをより特殊化/最適化できます より詳細なレベルでリソースへのアクセスを制御する機能 単一の統合モデルの長所 複数のドメインに属するコンセプトの重複リソースはありません ユーザーが複数のドメインで作業する必要がある場合は、すべてのニーズに対応する単一のAPIを使用するだけで済みます 上記のAPIパーティショニングは、APIコントラクトと実装の両方の複雑さを軽減する有効な方法ですか?私はそれがどこにも言及されているのを見たことがありません。 どちらかのアプローチを支持して決定を下すために検討する必要があるものは他にありますか?

2
アクセストークンを使用したAPIの設計、GETリクエストの処理方法
さまざまな部門間の使用状況を追跡したり、アクセス制御を行うために、アクセストークンを利用するAPIを構築しています。私の計画は、HTTP動詞を適切に利用することです- GET情報の取得、POST追加、DELETE削除などを行います。 私の質問は、GET呼び出しでアクセストークンをどのように処理する必要があるかです。 オプション1: クエリ文字列の一部としてアクセストークンを提供することです/api/users/?token=ACCESSTOKEN。これで私が抱えている問題は、ACCESSTOKENがサーバーログに表示されることです。このメソッドは、本文を介してトークンが渡されるPOSTまたはDELETEリクエストとも異なります。 オプション2: (POSTリクエストで行うように)リクエストに本文を指定します。パラメータの1つはトークンです。ここでの問題は、社内の他の開発者が、データを渡しているため、これは「真のGETリクエスト」ではないと言っていることです。彼らが呼び出すURLは単純にこのように/api/users/なりtoken=ACCESSTOKEN、本文内に提供されます。 オプション3: 使用GETを中止し、すべてをに強制しますPOST。これらのAPI呼び出しの多くでは、新しいリソースを作成していないため、このアイデアは好きではありません。私は単に、承認が必要なAPIの背後にあるデータを返すだけです。 私が見当たらない、または調整する必要があるオプションはありますか?私はオプション2が好きですが、他の部門の開発者の懸念に敏感です。

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