Web-APIについての考え。 パート1

ある時点で、次のWebサービスを作成する過程で、クライアントアプリケーションのニーズを満たすWeb-APIの設計に関するすべての知識と考えを収集し、それらを記事または一連の記事の形式で配置することにしました。 もちろん、私の経験は絶対的なものであると主張しているわけではなく、建設的な批判や追加は大歓迎です。



読書は技術的なものより哲学的であることが判明しましたが、技術的な部分のファンにとっては、ここで反省するものがあります。 この記事で根本的に新しいこと、あなたが聞いたことがない、読んだことがない、そしてあなた自身が考えていなかったものを言うことを疑います。 私はすべてを単一のシステムに入れようとします。まず第一に自分の頭の中に入れます。これにはすでに多くの価値があります。 それにもかかわらず、私の考えがあなたの練習であなたに役立つならば、私はうれしいです。 行きましょう。



アプローチ1:アクター



クライアントとサーバー



この場合、サーバーは、HTTPリクエストを受信し、処理し、正しい答えを返すことができるネットワーク上の抽象的なマシンであると考えます。 この記事の文脈では、物理的な本質と内部アーキテクチャは、学生のラップトップであろうと、世界中に散らばる産業用サーバーの巨大なクラスターであろうと、絶対に重要ではありません。 同じ範囲で、あなたがドアの下で何を要求するか、ApacheまたはNginx、不明な獣、PHP、PythonまたはRubyがそれを処理し、使用するデータストア(Postgresql、MySQLまたはMongoDB)を生成します。 。 主なことは、サーバーが主なルールを満たしていることです-聞き、理解し、答えることを許します。



クライアントも、HTTP要求を形成して送信できるものであれば何でもかまいません。 この記事の特定の点まで、クライアントがこのリクエストを送信することで自分自身に設定する目標や、彼が答えをどうするかについても特に興味はありません。 クライアントは、ブラウザーで実行されているJavaScriptスクリプト、モバイルアプリケーション、サーバーで実行されている悪(またはそうではない)デーモン、またはスマートすぎる冷蔵庫(既にいくつかあります)である可能性があります。



ほとんどの場合、上記の2つの間の通信方法について話し合います。この2つの方法は、お互いを理解し、誰も質問しない方法です。



REST哲学



REST(Representational State Transfer)は元々、直接ネットワークストレージ(サーバー)を使用したいくつかの基本的な操作(データ抽出(GET) 、保存(POST) 、変更(PUT / PATCH)および削除を含む、データ管理用のシンプルで明確なインターフェースとして考えられていました(削除) 。 もちろん、このリストには常に、リクエストのエラー処理(リクエストが正しく構成されているかどうか)、データのアクセス制御(突然これを知っているべきではありません)、着信データの検証(突然あなたがナンセンスを書いた)などのオプションが含まれています。サーバーは、クライアントの要望を満たす前にこれを満たします。



さらに、RESTには多くのアーキテクチャ原則があり、そのリストはRESTに関する他の記事に記載されています。 それらが手元にあるようにそれらを簡単に見てみましょう、そして私はどこにも行かなくてもよかったです:



クライアントからのサーバーの独立性 -サーバーとクライアント間のインターフェースは変わらないため、サーバーとクライアントは互いに独立して即座に置き換えることができます。 サーバーはクライアントの状態を保存しません。



リソースアドレスの一意性 -(ネストの程度に関係なく)データの各ユニットには、本質的に一意のリソース識別子である独自の一意のURLがあります。



例: GET / api / v1 / users / 25 / name



データ保存形式と送信形式の独立性 -サーバーは、同じデータ(JSON、XMLなど)を転送するためのいくつかの異なる形式をサポートできますが、サポートされている形式に関係なく、内部形式でデータを保存します。



応答に必要なすべてのメタデータが存在する -データ自体に加えて、サーバーはリクエスト処理の詳細、たとえばエラーメッセージ、ページナビゲーションを正しく表示するためのコレクション内のレコードの総数など、それをさらに処理するために必要なリソースのさまざまなプロパティを返す必要があります。 また、さまざまなリソースについても説明します。



欠けているもの



クラシックRESTは、クライアントがフラットデータウェアハウスと同様にサーバーで動作することを意味しますが、クライアント間のデータの接続性と相互依存性については何も言われていません。 これらはすべて、デフォルトでは、クライアントアプリケーションに完全に依存しています。 ただし、ソーシャルサービスであろうとインターネットマーケティングシステムであろうと、データ管理システムが開発されている現代の主題分野は、データベースに格納されたエンティティ間の複雑な関係を意味します。 これらの関係のサポート、つまり データの整合性は、サーバー側の責任の範囲内にありますが、クライアントはこのデータにアクセスするためのインターフェイスにすぎません。 それでは、RESTに何が欠けているのでしょうか?



関数呼び出し



データ管理の別の方法として機能を区別する必要性は、メソッドのカプセル化、トランザクションのアトミック性、およびデータ整合性の維持の原則が施行されるという事実によって決定されます。 データとそれらの間の関係を手動で変更しないようにするには、リソース(単一オブジェクトまたはコレクション)で関数を呼び出し、必要なパラメーターを引数として「フィード」します。 この操作はREST標準に適合せず、特別な動詞も、関数の名前を示す方法もないため、開発者はそこから抜け出せます。



最も簡単な例は、ユーザー認証です。 関数POST / api / v1 / auth / loginを呼び出し、資格情報を含むオブジェクトを引数として渡し、その代わりにアクセスキーを取得します。 サーバー側のデータで何が起きているかは気にしません。



別のオプションは、エンティティ間の関係を作成および解除することです。 たとえば、ユーザーをグループに追加します。 グループエンティティでPOST / api / v1 / groups / 1 / addUser関数を呼び出し、ユーザーオブジェクトをパラメーターとして渡し、結果を取得します。 もちろん、例は非常にフェッチされますが、多くの場合、接続を作成するときに、サーバー側でデータを使用した追加の操作が可能です。



また 、データの保存に直接関係しない操作もあります。たとえば、通知の送信、操作の確認または拒否(レポート期間の完了など)です。



次の記事の1つで、これらの操作を分類し、実際に遭遇した操作に基づいて、可能な要求と応答のオプションを提案します。



複数の操作



多くの場合、クライアント開発者は、クライアントアプリケーションが1つの要求で一度に複数の同種のオブジェクトを作成/変更/削除/作成する方が便利であり、各オブジェクトが独自のサーバー側判定を持つことができることを理解しています。 少なくともいくつかのオプションがあります。すべての変更が完了しているか、一部のオブジェクトに対して部分的に実装されているか、エラーが発生しています。 まあ、いくつかの戦略があります:すべての人に成功した場合にのみ変更を適用し、部分的に適用するか、エラーが発生した場合にロールバックします。これはすでに本格的なトランザクションメカニズムを利用します。



web-apiについては、理想を目指して、何らかの形でこのような操作をシステムにもたらしたいと思います。 続編の一つでこれをやろうと思います。



統計クエリ、アグリゲーター、データ形式



サーバーに保存されたデータに基づいて、統計圧縮やデータを特別な方法でフォーマットする必要があることがよくあります。たとえば、クライアント側でグラフを作成する場合です。 実際、これはオンデマンドで生成されたデータであり、ある程度はオンザフライで読み取り専用であるため、別のカテゴリに分類するのが理にかなっています。 統計の際立った特徴の1つは、私の意見では、一意のIDがないことです。



これは、実際のアプリケーションを開発する際に遭遇する可能性のあるものとはほど遠いものであり、追加や修正が行われることを嬉しく思います。



さまざまなデータ



オブジェクト



クライアントとサーバー間の通信における主要なデータ型はオブジェクトです。 本質的に、オブジェクトはプロパティとそれに対応する値のリストです。 オブジェクトをリクエストでサーバーに送信し、リクエストの結果をオブジェクトとして取得できます。 さらに、オブジェクトは、少なくとも送信または受信された形でデータベースに保存されている実際のエンティティである必要はありません。 たとえば、承認の資格情報はオブジェクトとして送信されますが、独立したエンティティではありません。 データベースに格納されているオブジェクトでさえ、たとえば、作成日と編集日、さまざまなシステムラベルとフラグなど、追加のシステム内固有のプロパティを取得する傾向があります。 オブジェクトのプロパティは、独自のスカラー値にすることも、オブジェクトの一部ではない関連オブジェクトおよびオブジェクトのコレクションを含めることもできます。 オブジェクトのプロパティの一部は編集可能、システムの一部は読み取り専用、一部は本質的に統計的であり、その場で計算できます(たとえば、いいねの数)。 ユーザーの権限によっては、オブジェクトの一部のプロパティが非表示になる場合があります。



オブジェクトコレクション



コレクションといえば、同種のオブジェクトのリストで作業できるようにする一種のサーバーリソースを意味します。 オブジェクトを追加、削除、変更し、それらから選択します。 さらに、理論的には、コレクションには独自のプロパティ(たとえば、ページあたりの最大要素数)と機能(ここでは混乱していますが、これも起こりました)があります。



スカラー値



純粋な形では、私の記憶の中の独立したエンティティとしてのスカラー値は非常にまれでした。 通常、それらはオブジェクトまたはコレクションのプロパティとして考えられたため、読み取りと書き込みの両方で使用できる場合があります。 たとえば、ユーザー名を個別に取得して変更することができますGET / api / v1 / users / 1 / name 。 実際には、この機能が役立つことはめったにありませんが、必要に応じて手元に置いておきたいと思います。 これは、コレクションのプロパティ、たとえば投稿の数(フィルタリングの有無にかかわらず)に特に当てはまります: GET / api / v1 / news / count



ファイル



ファイルはファイルです-それらは単一の不可分な単位と見なされるべきです。 もう1つの質問は、ほとんどの場合、ファイルをデータベースに保存するときに、このファイルのメタデータ(サイズ、実名、ステータスなど)を含むサービスエンティティを作成できることです。



継続するには...



All Articles