7

私の状況は次のとおりです。

空港に関する地理情報を保持する正規化されたデータベースがあります。構造は次のとおりです。

airport --is in--> city --is in--> country --is in--> continent

ここで、データベースへの直接アクセスを許可せずに、ユーザーがこのデータを管理できるようにしたいと考えています。この管理インターフェースを Web サービス経由で提供する必要があります。

さて、サービスの設計に関しては、操作を定義する方法についての議論に出くわしました。私たちはさまざまな解決策を考え出しました:

ソリューション A: 特定の操作

4 つのテーブル (空港、都市、国、大陸) のそれぞれに対して、3 つの操作を定義します。

  • 入れる
  • 得る
  • アップデート

これにより、2 つの要求/応答オブジェクト = 24 オブジェクトで 12 の操作が発生します。

すべての依存関係を持つまったく新しい空港を作成するには、少なくとも 4 つのリクエストが必要です。

ソリューション B: 一般的な

パラメータによって制御される操作は 1 つだけです。この操作では、データベースの管理に必要なすべてを作成できます。

操作は、何を行う必要があるかを決定し、それを実行します。エラーが発生すると、すべてがロールバックされます。

==> 1 つの操作 = 2 つの非常に複雑な要求/応答オブジェクト

ソリューション C: 途中で会う 1

テーブルごとに 1 つの一般的な操作。ソリューション B と同様に、取得、挿入、更新を実行できますが、それぞれ 1 つのテーブルに焦点を当てています。

==> 4 つの操作 = 8 つの複雑な要求/応答オブジェクト

ソリューション D: 真ん中で会う 2

アクションごとに 1 つの一般的な操作 (取得、挿入、削除)。これは、各テーブルで機能し、依存関係を解決できます。

==> 3 つの操作 = 6 つのもう少し複雑な要求/応答オブジェクト

これはかなり抽象的だったので、リクエストオブジェクトを作成するための単純化された例 (JFK/New York/USA/North America) を以下に示します。

ソリューション A:

リクエスト 1/4:

<insertContinent>North America</insertContinent>

リクエスト 2/4:

<insertCountry continent="North America">USA</insertCountry>

リクエスト 3/4:

<insertCity country="USA">New York</insertCity>

リクエスト 4/4:

<insertAirport city="New York">JFK</insertAirport>

ソリューション B:

リクエスト 1/1:

<action type="insertCountry" parent="North America">USA</action>
<action type="insertAirport" parent="New York">JFK</action>
<action type="insertContinent" parent="">North America</action>
<action type="insertCity" parent="USA">New York</action>

ソリューション C:

リクエスト 1/4:

<countryAction type="insert" parent="North America">USA</countryAction>

リクエスト 2/4:

<airportAction type="insert" parent="New York">JFK</airportAction>

リクエスト 3/4:

<continentAction type="insert" parent="">North America</continentAction >

リクエスト 4/4:

<cityAction type="insert" parent="USA">New York</cityAction >

ソリューション D: リクエスト 1/1:

<insert airport="JFK" city="New York" country="USA" continent="North America" />

ソリューション D は私にとってかなりエレガントに思えるので、これを XSD に入れようとしました。

コード:

<complexType name="NewContinent">
    <sequence>
        <element name="NAME" type="string"></element>
    </sequence>
</complexType>

<complexType name="NewCountry">
    <sequence>
        <element name="ISOCODE" type="string"></element>
        <element name="NAME" type="string"></element>
        <choice>
            <element name="newCONTINENT" type="tns:NewContinent"></element>
            <element name="CONTINENT" type="string"></element>
        </choice>
    </sequence>
</complexType>

<complexType name="NewCity">
    <sequence>
        <element name="IATA" type="string"></element>
        <element name="NAME" type="string"></element>
        <choice>
            <element name="COUNTRY" type="string"></element>
            <element name="newCOUNTRY" type="tns:NewCountry"></element>
        </choice>
    </sequence>

</complexType>

<complexType name="NewAirport">
    <sequence>
        <element name="IATA" type="string"></element>
        <element name="NAME" type="string"></element>
        <choice>
            <element name="CITY" type="string"></element>
            <element name="newCITY" type="tns:NewCity"></element>
        </choice>
    </sequence>

</complexType>

対応するリクエストは次のようになります。

<complexType name="Request">
    <choice>
        <element name="AIRPORT" type="tns:NewAirport"></element>
        <element name="CITY" type="tns:NewCity"></element>
        <element name="COUNTRY" type="tns:NewCountry"></element>
        <element name="CONTINENT" type="tns:NewContinent"></element>
    </choice>
</complexType>

今私の質問:これは本当に利用可能な最善の解決策ですか? XSD は何が起こっているのかを理解するのに十分ですか?

4

2 に答える 2

5

おそらく、さまざまなメッセージタイプを理解するプロトコルレイヤーを作成しているはずです。また、メッセージの内容を解析するためのアプリケーション層も必要になります。あなたが言及する異なるアプローチは、これらの2つの層の間で構文解析の負担をシフトします。したがって、たとえば:

解決策A:プロトコル層はすべての解析を実行し、データとコマンドを返します。アプリケーション層はデータを使用するだけです。これは、RPCパターンとも呼ばれます。

長所:メッセージを検証できます。メッセージをアプリケーション呼び出しに直接マップできます。

短所:インターフェースを変更する必要がある場合は、プロトコルが変更されます。

解決策B:プロトコル層は2つの値と1つのコマンドを返します。アプリケーション層は、コマンドを使用して値を型に解析する必要があります。

長所:プロトコルは変更されません。

短所:メッセージを検証できません。アプリケーションコードはもっと複雑です。

解決策C:プロトコルレイヤーは、2つの既知のタイプと解析する必要のあるコマンドを返します。アプリケーション層は、コマンドを解析してデータを使用するだけです。

長所:私は何も考えられません、あまり良い妥協ではないようです。

短所:解析は部分的にしか実行されません。

解決策D:プロトコルレイヤーは、既知のタイプ(実装方法)と汎用コマンドを返します。アプリケーション層は、受信したデータを確認し、汎用コマンドを特定のコマンドに変換する必要があります。これはRESTアーキテクチャに似ています。

長所:呼び出しは別個の操作であるため、たとえば、get応答をキャッシュできます。

短所:アプリケーション層の複雑さ

通常、RESTモデルは、概説したものとは異なる方法で実装されます。HTTP GET、POST、PUT、DELETEメッセージを使用して、任意のドキュメントを通信します。パラメータはURLの一部として提供されます。したがって、たとえば:

<insert airport="JFK" city="New York" country="USA" continent="North America" />

になります

<insert URL="airport?city=Chicago">ORD</insert>

または、HTTPを使用している場合は、空港に関する情報を含む都市のパラメータを含む空港URLへのPOSTリクエストになります。複数の要素と混合型がある場合、より複雑なデータを使用すると、この一部がより明確になることに注意してください。たとえば、空港の略語、長い名前、高度を送信する場合です。

あなたが説明するインターフェースでは、RESTアーキテクチャーが非常にうまく機能すると思います。あなたがする必要があるのは、CRUD操作をサポートすることだけです。RESTアーキテクチャスタイルの長所と短所を提供する多くのサイトがあります。

個人的には、RESTフル属性を備えたRPCスタイル(ソリューションA)が好きです。プロトコルに解析作業を実行させ、メッセージを検証してもらいたい。これは通常、人々がSOAPWebサービスインターフェイスを実装する方法です。

今日のインターフェースはシンプルに見えるかもしれませんが、明日、顧客の1人が、RESTモデルにあまり適合しない新しい呼び出しを要求し、既存の4つのメッセージにそれを押し込んでいることに気付くでしょう。

于 2008-10-08T19:42:06.737 に答える
1

これは古い質問であり、サービスはずっと前に書かれたものだと思いますが、とにかく回答を提供したかったのです。

RESTful なアプローチは、次のような空港リソースを定義することです。

<airport href="/airports/JFK">
    <name>JFK</name>
    <city>New York</city>
    <country>USA</country>
    <continent>North America</continent>
</airport>

または、ブラウザ互換のマイクロフォーマットを使用する場合:

<div class="object airport" href="/airports/JFK">
    <ul class="attributes"> 
        <li class="name">JFK</li>
        <li class="city">New York</li>
        <li class="country">USA</li>
        <li class="continent">North America</li>
    </ul>
</div>

このリソースは のような URI に配置され、メソッドで/airports/JFK取得され、GETメソッドで更新され、PUTメソッドで削除されDELETEます。

このような設計では、URI/airports/はデータベース内のすべての空港のコンテナー リソースを表し、 URI は空港のサブセットを返すためのコンテナーのフィルター/airports/?city=New+Yorkとなります。/airports/?country=USAこれらは両方ともGETメソッドであり、リソースには上記で定義した空港リソースのリストが含まれます。これには、完全な (小さいため) またはいくつかの有用な属性と、href各空港の完全なリソースを指す があります。

最後に、新しいリソースの追加はPUT、空港の完全な URI のメソッドか、 のメソッドのPOSTいずれか/airports/です。どちらの場合も、要求の本文は上記の空港リソースです。これらの方法の違いは、空港の最終的な URI を誰が決定するかです。つまり、クライアントが決定しPUT、サービスが決定しPOSTます。どちらを使用するかは、クライアントが適切な URI を合理的に判断できるかどうかによって異なります。通常、URI には一意の数値識別子が含まれており、サービスがそれを選択する必要があるため、サービスが決定します。

もちろん、最初の質問は REST ではなく SOAP に関するものでした。GET先に説明したように RESTful 設計をセットアップしてから、RESTful サービスの、PUTDELETE、および操作を複製するアクションを持つ XSD および SOAP サービスを使用して、リソースを複雑な型として記述しPOSTます。これにより、以下に相当する RPC が得られます。

class Airport
    has String name
    has String city
    has String country
    has String continent
    method void update(name, city, country, continent)
    method void delete()

class AirportList
    method Airport[] get(opt name, opt city, opt country, opt continent)
    method void add(name, city, country, continent)
于 2010-07-17T17:13:36.703 に答える