8

Hypermedia をうまく活用した RESTful サービスを設計しようとしています。
できれば、サービスのすべての機能を探索できるように、ユーザー エージェントはルート URI のみを知っている必要があります。つまり、成熟度モデルの第 3 レベルにあることを望みます。

これで、ユーザー エージェントはいくつかのリソースを作成し、後でそれらを編集できるようになります。作成/編集時に、ユーザー エージェントは他のリソース/列挙にアクセスする必要があります。

fooリソース:

{
    "category" : "category chosen from an enumeration of possible categories",
    "color" : "color chosen from an enumeration of possible colors",
    "aRelatedResource" : "resource identifier from chosen from a collection"
}


前述の要件を考慮して、次のパターンを考え出しました。

fooRootリソースを用意します。

{
    // no properties, only links
    "_links" : { 
        "foos" : { "href" : "URI-to-foos" },
        "fooCreator" : { "href" : "URI-to-plain-fooWriter" }
    }
}

fooリソースにfooWriterへのリンクを含めます。

fooリソース:

{
    "category" : "category chosen from an enumeration of possible categories",
    "color" : "color chosen from an enumeration of possible colors",
    "aRelatedResource" : "resource identifier from chosen from a collection",
    "_links" : {
        "self" : {...},
        "fooEditor" : { "href" : "URI-to-fooWriter-initialized-for-current-foo" }
    }
}

fooWriterは次のようになります。

{
    "fooPayload" : {
        "category" : "NULL or pre-initialized",
        "color" : "NULL or pre-initialized",
        "aRelatedResource" : "NULL or pre-initialized"
    },
    "_links" : {
        "fooPayloadDestination" : { "href" : "URI-to-foos-or-foo" },
        "categoryEnum" : { "href" : "URI-to-categories" },
        "colorEnum" : { "href" : "URI-to-colors" },
        "availableResourcesToRelateWith" : { "href" : "some-other-URI" },
        ....
        .... and even something useful for pre-validation etc.
        "validator" : { href : "URI-to-some-resource-or-service" }
    }
}

要約すると、作成および編集できるすべてのリソースには、ライターリソースが関連付けられている可能性があります。writer
を GET することにより、ユーザー エージェントは非常に便利な方法でリソースを作成/編集できます。 ライターに埋め込まれたペイロードは、その宛先に POST され、ほら :)

また、リソースと新しいリソースのライターの両方へのリンクを保持するルートコンテナが必要です (上記の例のfooRootを参照)。



質問は...

...上記のパターンにはよく知られている名前がありますか? ...作成/編集時に隣接するリソースが必要であり、第 3 レベルの成熟度がまだ「保持」されている、作成/編集
の問題 を解決するより良い方法はありますか?

参考文献:

4

2 に答える 2

1

あなたが説明していることは、フォームリンク関係の作成と編集を少し思い出させます。ただし、API を構築している場合は、その定義方法に関係なく、だれかが API をプログラミングする必要があるため、その使用はかなり制限されます。

私の意見では、上記の例を整理する最も簡単な方法は、次のようなルート メニューを定義することです。

GET / HTTP/1.1
Accept: application/hal+json
----
HTTP/1.1 200 OK
Content-Type:application/hal+json

{
    "_links" : { 
        "plants" : { "href" : "/plants" }
    }
}

plantsリレーションは、特定のメディア タイプ ( だとしましょうapplication/vnd.biology-example-org.plant) によって定義された植物リソースのコレクションを保持します。

GET /plants HTTP/1.1
Accept: application/hal+json
----
HTTP/1.1 200 OK
Content-Type:application/hal+json

{
    "_links" : { 
        "self" : { "href" : "/plants" },
        "plant": [
          {
            "href" : "/plants/parsnip",
            "title" : "The Parsnip",
            "type" : "application/vnd.biology-example-org.plant+json"
          }
        ]
    }
}

パースニップに関連するコレクションに新しい植物を追加するには、plantsコレクション リソースに POST し、そのリンクを介してパースニップに関連付けます。

POST /plants HTTP/1.1
Content-Type: application/vnd.biology-example-org.plant+json

{
    "title" : "The Carrot - a cousin of the Parsnip",
    "category" : "vegetable",
    "color" : "orange",
    "related" : [ "/plants/parsnip" ]
}
----
HTTP/1.1 201 Created
Location: http://biology.example.org/plants/carrot

その後ニンジンを変更するには、返された URL に PUT を発行します。

PUT /plants/carrot HTTP/1.1
Content-Type: application/vnd.biology-example-org.plant+json

{
    "title" : "The Carrot - the orange cousin of the Parsnip",
    "category" : "vegetable",
    "color" : "orange",
    "related" : [ "/plants/parsnip" ]
}
----
HTTP/1.1 200 OK

上記の例では、Hypertext Application Language (HAL) を使用して、JSON を使用して「レベル 3」REST セマンティクスを通信します。HAL はシンプルですが非常に強力です。私が本当に気に入っている規則の 1 つは、リレーション名URI として使用することです。この URI は、逆参照されると、そのリレーションとそれが返すリソースに関するドキュメントを直接指します。

このようなライブ API を試してみたい場合は、HAL のライブ デモ API であるHALtalkを見ることを強くお勧めします。

于 2014-09-01T15:22:02.697 に答える
0

質問してみましょう。リソースを編集するには何が必要ですか?

  • HTML では、FORM タグとその中に INPUT タグが必要です。

彼らは何を説明していますか?

  • 1.) フォームです。
  • 2.) アクション IRI を持っています。
  • 3.) メソッドがあります。
  • 4.) コンテンツ タイプがあります。
  • 5.) 複数のフィールドがあり、ユーザーが入力する必要があります。おそらく検証データを使用します。

あなたが得たフォームで:

  • 6.) フォーム全体のタイトル
  • 7.) 入力フィールドのラベル

これは、REST クライアントが必要とするものとほぼ同じです。

  • 8.) すでに認識している REST クライアントのリンク関係を含める必要があるため、クライアントはそれを使用してフォームを適切なコンテキストに配置します。(これは HTML による RDFa で行うことができます。)

以上ではなく、それ以上でもありません。

次に、私のお気に入りの 2 つの JSON メディア タイプ別に現在のオプションを見てみましょう (コレクション + json、shiren など、他にも多くの JSON ハイパーメディア タイプがあります)。

HAL+JSON

HALによって、埋め込みリソースを定義し、それらにリンクを追加できます。

{
  "_links": {
    .. *snip* ..
  },
  "_embedded": {
    "manufacturer": {
      "_links": {
        "self": { "href": "/manufacturers/328764" },
        "homepage": { "href": "http://hoverdonkey.com" }
      },
      "name": "Manufacturer Inc."
    },
    "review": [
      {
        "_links": {
          "self": { "href": "/review/126" },
          "customer": { "href": "/customer/fred", "title": "Fred Wilson" }
        },
        "title": "Love it!",
        "content": "I love this product. I also bought a Hover Donkey with it.",
        "rating": 10
      },
      ...
    ]
  },
  "name": "A product",
  "weight": 400,
  .. *snip* ..
}

_link はここで 1.) を説明し、href はここで 2.) を説明し、link title は 6.) を説明し、link-relation は 3.) と 8.) を説明します。content-type 4.) と、必要なフィールドに関するメタデータ (検証、ラベル 5.) および 7.) が必要です。

ここでどのような選択肢がありますか?

  • HAL+JSON をある程度拡張し、フィールド プロパティを各リンクに追加するか、
  • フィールドを説明するベンダー固有のコンテンツ タイプを追加できます。

JSON-LD + ヒドラ語彙

hydra vocabを使用するhydra:Linkと、RDF (通常は JSON-LD) ドキュメントの に操作を追加できます。

{
    "@context": {
        "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
        "hydra": "http://www.w3.org/ns/hydra/core#",
        "vocab": "/vocab#",
        ...
        "title": {
            "@id": "vocab:Issue/title",
            "@type": "hydra:property",
            "rdfs:range": "xsd:string",
            "rdfs:label": "Issue title"
        },
        "comments": {
            "@id": "vocab:comments",
            "@type": "hydra:Link",
            "hydra:supportedOperation": [
                {
                    "@id": "vocab:create-comment",
                    "@type": "hydra:CreateResourceOperation",
                    "rdfs:label": "Creates a new comment",
                    "hydra:method": "POST",
                    "hydra:expects": "vocab:Comment",
                    "hydra:returns": "vocab:Comment"
                }
            ]
        }
    },
    "@id": "/issues/cso29ax",
    "id": "cso29ax",
    "created_at": "2012-12-10 12:45",
    ...
    "title": "Some random issue",
    "comments": {
        "@id": "/issues/cso29ax/comments/"
    }
}

オフ。実際には、 @context 部分全体を IRI の下の別のファイルに移動しますが、/vocabこの方法でそれが何をするかを確認する方が簡単です。RDF 文書では、主語、述語、目的語のトリプレットがあります。たとえば/issues/cso29ax、 、/ctx#Issue/title"Some random issue"はトリプレットにすることができます。したがって、「id」、「created_at」、「title」、「comments」は、@context.

したがって、ここでは、@context表現のコンテキストと、リンク関係を記述する/ctx#create-commentようなプロパティ名と操作名をhydra:CreateResourceOperation記述します 8.)。iana必要に応じて、の説明で語彙を使用できます/ctx#create-comment。それは、あなたと REST クライアントの機能に依存します。はhydra:Link、それがフォーム 1.) であると説明しています。は@id: "/issues/cso29ax/comments/"、アクション IRI を記述します 2.)。はrdfs:label、フォームのタイトルと入力フィールドのラベル 6.) および 7.) を記述します (多言語にすることができます)。content-type は常に JSON+LD 4.) です。HTTP メソッドはhydra:method3.) で記述され、検証データなどは および で記述されますhydra:expectshxdra:returns各プロパティの 5.) したがって、「@context」の一部です (この例では省きました)。したがって、RDF + hydra vocab によって、フォームを記述するために他に何も必要ありません。

おそらく必要なのは、同じリソースの複数の表現を定義することです。

たとえば、作成リンク、編集リンク、削除リンクなどの表現が必要で、データのみの表現が必要です。複数の方法でそれを行うことができます:

  • 表現ごとに、ベンダー固有のコンテンツ タイプを定義できます。
  • たとえば、リソースに新しい IRI を追加できます/issues/?data-only=1。(クエリは IRI の非階層部分に対するものであるため、リソース識別子の一部でもあります。単一のリソースは複数の識別子を持つことができるため、/issues//issues/?data-only=1は同じリソースを持つことができます。単一の識別子が複数のリソースに属することはできません。リソースですが、これは明らかだと思います。) したがって、あなたの場合、ライターとエディターのリソースを作成する必要はありません。複数の識別子 (IRI) を持つ単一のリソースがあれば十分です。
于 2014-09-01T18:30:52.450 に答える