5

Ich versuche eine RESTful Weise zu bestimmen, Subresources enthalten und für bestimmte Anforderungen beliebig ausgeschlossen werden.REST-API einschließlich und exklusive von Sub-Ressourcen

Zum Beispiel willen, könnte dies die ursprüngliche Anforderung sein:

GET Abteilungen/321

200 (Ok) 
{ 
    "id": "321", 
    "name": "Sales", 
    "building": "The Foundary" 
    "subdepartments": [ 
     { 
      "id": "123", 
      "name": "Training" 
     }, 
     { 
      "id": "224", 
      "name": "Book Sales" 
     } 
     ... 
    ] 
} 

Es könnte eine große Liste von Unterabteilungen sein. Die Ressource GET departments würde dann auch jede Abteilung UND jede Unterabteilung dieser Abteilungen einschließen. Viele Daten.

Dies könnte durch die Schaffung von zwei getrennten Ressourcen gelöst werden:

GET Abteilungen/321

200 (Ok) 
{ 
    "id": "3", 
    "name": "Sales", 
    "building": "The Foundary" 
} 

GET Abteilungen/321/Sub-Waren

200 (Ok) 
[ 
    { 
     "id": "123", 
     "name": "Training" 
    }, 
    { 
     "id": "224", 
     "name": "Book Sales" 
    } 
    ... 
] 

Aber es kann sein, Anlässe, bei denen die Client-Software es vorziehen würde, nicht mehrere Anfragen zu stellen (um der Leistung willen am wahrscheinlichsten). Vielleicht, indem ein include Filter:

GET Abteilungen/321 include = Unterabteilungen

200 (Ok) 
{ 
    "id": "321", 
    "name": "Sales", 
    "building": "The Foundary" 
    "subdepartments": [ 
     { 
      "id": "123", 
      "name": "Training" 
     }, 
     { 
      "id": "224", 
      "name": "Book Sales" 
     } 
     ... 
    ] 
} 

oder ein Ausschluss-Filter:

GET Abteilungen/321 ausschließen = Unterabteilungen

200 (Ok) 
{ 
    "id": "321", 
    "name": "Sales", 
    "building": "The Foundary" 
} 

Obwohl wir vielleicht inc lude einen Link zu der Subresource, wenn sie ausgeschlossen ist?

GET Abteilungen/321? Ausschließen = Sub-Waren

200 (Ok) 
{ 
    "id": "321", 
    "name": "Sales", 
    "building": "The Foundary" 
    "subdepartments": { 
     "href" : "api.com/departments/321/subresources" 
    } 
} 

Gibt es eine akzeptable RESTful Weise, die oben von der Durchführung einschließlich oder ausschließlich von Subressourcen?

+2

Was Sie vorschlagen, sieht gut aus. Ich denke RESTful sollte nicht zu streng verwendet werden. Wenn deine Welt nicht in REST passt, dann sollte REST gebogen werden - nicht die Welt. – Kris

Antwort

1

Der richtige REST-Service hypermedia (Links kann) müssen zu verwandten Ressourcen verbinden. Wenn wir einen benutzerdefinierten Medientyp statt so etwas wie JSON-Sammlung oder AtomPub, die Antwort für den ersten Anruf in etwa so aussehen

verwenden würde
{ 
    "id": "321", 
    "name": "Sales", 
    "building": "The Foundary" 
    "links": [ 
      { "rel": "subdepartments", "href": "departments/321/subdepartments", "method": "get" } 
    ] 
} 

können Sie diesen Link aufrufen, eine Ressource mit Links zu allen Unterabteilungen zu bekommen.

{ 
    ... 
    "links": [ 
     { "rel": "subdepartment", "href": "departments/321/subdepartments/1", "method": "get" }, 
     { "rel": "subdepartment", "href": "departments/321/subdepartments/2", "method": "get" } 
    ] 
} 

Es funktioniert fast wie Durchsuchen einer Website und klicken Sie auf die Links.

Lesen Sie diesen Blog-Eintrag von Roy Fieldings selbst: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

Es gibt offensichtliche Komplexität und Performance-Probleme, die in diesem Ansatz passieren könnte. Echte REST-konforme Dienste sind sinnvoll, wenn sich die Server-App separat vom Client entwickeln kann. Andernfalls verwenden Sie einfach den Ansatz mit Abfragezeichenfolgenparametern.

+0

Danke. Würde es einen Wert geben, den href wie in meinem letzten Beispiel bereitzustellen? – davenewza

+1

Es hängt wirklich davon ab, dass der Client den Dienst nutzt. Es kann eine gute Idee sein, Links standardmäßig bereitzustellen und einen OData-Style-Abfrageparameter "$ expand = true" zu verwenden, um Links durch tatsächliche Ressourcen zu ersetzen. –

+0

Ich bin mir nicht sicher, ob irgendetwas in REST ein * Muss * ist. – Opal

2

Ich habe kein Problem, diese Parameter hinzuzufügen, also gehen Sie voran und verwenden Sie es, der wichtigste Teil ist, dass Sie den HTTP-Status-Code verwalten, eine Antwort haben eine gute Struktur, um die Daten zu lesen (und Sie haben it)

auch wenn Sie eine andere Art und Weise sehen wollen, tru mit OData: Web API and OData

1

das klingt nach einer sehr guten Passform für http://jsonapi.org/ - Es ist "Ihre Anti-Bikeshedding-Waffe", wenn es darum geht, Ihre JSON-Antworten zu strukturieren. Das Lesen der Spezifikation kann im Vergleich zur Implementierung eines eigenen Ad-hoc-Schemas zunächst etwas Zeit in Anspruch nehmen, aber es zahlt sich wirklich aus. Die Spezifikation besteht auch aus einem Teil section about "compound documents", der auch einen include=… Parameter verwendet, um mehrere Dokumente/Ressourcen mit einer Anforderung abzurufen.