2011-06-30 1 views
2

私は旅行計画アプリケーションを持っていて、各旅行は一連のポイントとして構成された「経路」リソース(例えば、駆動されるルートを表す)で構成されているとします。次のようなリクエストを使用してこれらのリソースをCRUDできます。どのようにしてRESTfulで作成して同時に削除しますか?

POST /trips/1234/paths 

<Path> 
    <Point>32,32</Point> 
    <Point>32,34</Point> 
    <Point>34,34</Point> 
</Path> 

DELETE /trips/1234/paths/3 

ここで、Pathを2つのパスに分割できるようにしたいと考えています。 Aobveの例では、スプリットするポイント(32,34)を選んで、2つのパスになります。そのポイントはそのポイントで終了し、そのポイントで始まります。つまり、1つのアクションで2つの新しいリソースが作成されると同時に、別のリソース(分割されたパス)が削除されます。

したがって、上の例のパスがシステム内の唯一のパスであって、1回の呼び出しで分割した場合、システムには2つの新しいパスが含まれ、元のパスはなくなります。例:

<Path> 
    <Point>32,32</Point> 
    <Point>32,34</Point> 
</Path> 

<Path> 
    <Point>32,34</Point> 
    <Point>34,34</Point> 
</Path> 

これはどのようにRESTfullyで処理するのかと苦労しています。どのようにして、複数のリソースが作成/変更/削除され、それを呼び出し側に伝える呼び出しを処理しますか?

私は間違いなく複数の呼び出し(新しいパスを作成するための2つのPOSTと元のものを削除するDELETE)を使用してそれを把握することができますが、これを1回の呼び出しにします。

答えて

1

で解決することができ、私はまだそれ少しRPCish作る@Darrel Miller's答えのようにそれを実装しようとするだろう。 考えてみましょうPathSplitリソースを作成して、クライアントがトランザクションを完了するための各ステップを誘導するようにします。このようにして、クライアントは各ステップの結果を把握しており、途中でエラーがあった場合は元に戻すことができます。

このようなものは、このトリックを行う必要があります。このクライアントのようなもので

POST /pathsplit HTTP/1.1 
Content-Type: application/vnd.acme.pathsplit+xml 
<pathsplit xmlns="http://schema.acme.com"> 
    <path> 
    <id>123</id> 
    </path> 
    <splitpoint> 
     <point>32,34</point> 
    </splitpoint> 
</pathsplit> 

=> 
HTTP/1.1 201 Created 
Content-Type: application/vnd.acme.pathsplit+xml 
Location: 
    http://acme.com/pathsplit/11 

<pathsplit xmlns="http://schema.acme.com"> 
    <path> 
    <id>123</id> 
    </path> 
    <splitpoint> 
     <point>32,34</point> 
    </splitpoint> 
    <newpaths> 
    <Path> 
     <Point>32,32</Point> 
     <Point>32,34</Point> 
    </Path> 
    <Path> 
     <Point>32,34</Point> 
     <Point>34,34</Point> 
    </Path> 
    <createuri>http://acme.org/trips/paths</createuri> 
    </newpaths> 
    <oldpath> 
    <uri>http://acme.org/trips/paths/123</uri> 
    </oldpath> 
    <status>in-progress</status> 
    <pathscreated>0</pathscreated> 
</pathsplit> 

は常にGET pathsplitリソースは、アクションを取るかを確認することができます。この例では、createuriリンクの後に新しいpathsが新しく作成され、それぞれ新しいpathnewpathsPOSTリクエストが送信されます。サーバーは、新しいリソースがそれぞれ作成されるたびに状況を更新します。

ステータスがpathscreatedであれば、クライアントはurlに続いてDELETE動詞を送信することで、古いpathを削除できます。最後に、pathplitリソースを削除し、すべてが成功したことを示します。エラーの場合、またはネットワーク障害のすべてあまりにも一般的なケースでは道に沿ってステップごとに、時

、クライアントは常にサーバーが内にあり、どのような状態のトランザクションがでている状態を知っている。

トランザクションが完了していない限り、pathsplitリソースは利用可能なままです。 クライアントには、まだ完了していないトランザクションを元に戻すオプションもあります。ここでも、どの操作が正常に完了し、どの操作が正常に完了したのかが分かっているため、いつでもトランザクションを取り消すことができます。

+0

ああ...これは私が探していたものです。私はクライアントがスプリットを実行するワークフロー(私はあなたの提案が好きですが)を歩くのではなく、依然として単一の要求であることを依然として望んでいると思います。私は一定期間の間にパス分割リソースを維持することができます。クライアントは後でそのファイルを削除して分割を元に戻したり、しばらくしてから、サーバーはパス分割リソースを削除して元に戻すことができます。思考? – SingleShot

+0

pasthsplitリソースを元に戻すと、元に戻すことができます。これにより、APIのユーザーに混乱が生じます。 DELETE verbはリソースの削除に使用され、予期されるアクションはそのリソースのみの削除です。あなたが示唆している場合は、リソースを削除するだけでなく、他のリソースを削除したり変更したりすることです。分割を元に戻したい場合は、pathsplitリソースのGETを行い、次にpayploadリソースとしてpathsplitリソースを持つ新しいundosplitリソースへのPOSTを実行します。 –

+0

undosplitリソースは、pathsplitリソースからスプリットを元に戻す方法を知っており、新しいリソースを作成して返すことができます。 「分割を元に戻す」とは、2つのリソースを削除し、新しいリソースを作成することです。これは、元の「分割されていない」と同じですが、同じインスタンスではありません。 –

1

簡単な答えは、これを1回の呼び出しにするだけでは実際にはRESTfulではないということです。あなたの表現を改造しない限り、RESTとHATEOASについての私の理解は、この種のプロセスが動詞をサーバーサイドの表現に挿入しようとしていることです。それはあなたがしたいことをRESTfulに行うことはできないと言っているわけではありませんが、私はそれがあなたの表現ツリーのリファクタリングを少し含んでいると思います。

次に、「なぜ」、これを単一の呼び出しにしたいのかという質問があります。私はトランザクションの観点から、それがなぜそれが理にかなっているのがわかります。これは、トランザクションREST表現をクライアントに公開することを意味するように見えるので、クライアントはトランザクションを適切に管理することができます。私は単純だと言っているわけではありません...

0

厳密なCRUD操作の解決法は、ここでは役に立たないようです。ただし、リソースに対する操作は必ずしもCRUD操作である必要はありません。多くの人々は、これをRESTインターフェース(rest + crud用のGoogleだけ)を設計する悪い方法と考えています。

したがって、分割操作を1回のREST呼び出しとして定義すると、まったく問題はないと思います。この操作を1つのリソース(元のパス)のみに適用すると、この操作を直接その上で定義することができます。複数のリソースで定義する必要はありません。

2

それは正確にきれいではありませんですが、これは「処理資源」

POST /PathSplitter?SplitAt=(32,34) 
Content-Type: application/vnd.acme.path+xml 
<Path> 
    <Point>32,32</Point> 
    <Point>32,34</Point> 
    <Point>34,34</Point> 
</Path> 

=> 
200 OK 
Content-Type: application/vnd.acme.pathlist+xml 
<Paths> 
    <Path href="/trips/1234/paths/4"/> 
    <Path href="/trips/1234/paths/5"/> 
</Path> 
関連する問題