soapサービスを定義する際のベストプラクティスは何ですか(一般的な操作と特定の操作)。

StackOverflow https://stackoverflow.com/questions/180572

  •  05-07-2019
  •  | 
  •  

質問

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

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

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

次に、ユーザーがデータベースに直接アクセスすることなく、このデータを管理できるようにします。この管理インターフェースをWebサービス経由で提供する必要があります。

今、サービスの設計に関しては、操作を定義する方法についての議論に出くわしました。さまざまなソリューションを思いつきました:

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

4つのテーブル(空港、都市、国、大陸)のそれぞれについて、3つのオペレーションを定義します:

  • 挿入
  • get
  • 更新

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

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

ソリューションB:汎用

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

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

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

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

テーブルごとに1つの汎用操作。ソリューションBと同様にget、insert、updateを実行できますが、それぞれ1つのテーブルに焦点を当てています。

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

ソリューションD:ミドル2で会いましょう

アクション(get、insert、delete)ごとに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" />

Solution 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は理解するのに十分ですか、何が起こっていますか?

役に立ちましたか?

解決

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

ソリューションA :プロトコルレイヤーはすべての解析を行い、データとコマンドを返します。アプリケーション層はデータのみを使用できます。これはRPCパターンとも呼ばれます。

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

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

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

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

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

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

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

短所:解析を部分的にのみ終了します。

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

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

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

通常、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-ful属性を持つRPCスタイル(ソリューションA)を好みます。プロトコルで解析作業を行い、メッセージを検証する必要があります。これは通常、SOAP Webサービスインターフェイスを実装する方法です。

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

他のヒント

これは古い質問であり、このサービスはかなり前に作成されたと確信していますが、とにかく回答を投稿したいと思いました。

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>

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

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

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

もちろん、元の質問はRESTではなくSOAPについてでした。先ほど説明したようにRESTfulデザインをセットアップし、XSDと、 GET PUT 、 DELETE 、および POST のRESTfulサービスの操作。これにより、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)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top