2016-08-05 34 views
1

Ich entwerfe eine REST-API, die von mehreren Clients verwendet wird, um ein Datenrepository abzufragen. Ich gehe davon aus, dass diese Kunden unterschiedliche Anforderungen hinsichtlich der Höhe/Detailliertheit der Antworten haben werden.Gute Methode für einen REST-API-Client, um die gewünschte Detailmenge der Antwort anzugeben?

Sagen wir, ich kann eine Sammlung von Büchern abfragen. Ein Buch könnte möglicherweise viele Attribute haben (mehr als jeder einzelne Client interessiert sein könnte), vielleicht sogar Unterressourcen, und ein Client könnte eine große Anzahl von Büchern anfordern, was zu einem Antworttextkörper führt, der größer als erforderlich ist.

Daher suche ich nach Möglichkeiten zur Optimierung der Antwortgröße. Die Idee ist, dem API-Client einige Mittel zu geben, um anzugeben, wie viele Details in die Antwort aufgenommen werden sollen.

Ich würde gerne erfahren, wie dieses Problem zuvor gelöst wurde; welcher Mechanismus in der Praxis gut funktioniert hat und welcher nicht, welches API-Design besonders RESTful ist und welches nicht, und so weiter.

ein paar Möglichkeiten, die ich denken kann ein Client, wie möglicherweise gewünschten Detaillierungsgrad für die Antwort geben konnte:

  • entweder mit dem GET oder HEADHTTP-Methode/Verb. Erstere würde alle Details zurückgeben, erstere nur eine Teilmenge.

    Dieser Ansatz ermöglicht uns nur die Unterscheidung zwischen zwei Detailebenen, daher ist er nur bedingt geeignet.

  • Mit einem Abfragezeichenfolgenparameter, der (nach Name) angibt, welche Eigenschaften/Attribute in der Antwort zurückgegeben werden sollen. Zum Beispiel:

    GET /books?include=title,author,publisher,...,preview 
    

    Dies bietet nahezu unbegrenzte Flexibilität, aber eben diese Flexibilität könnte schwierig sein, tatsächlich umzusetzen und befassen sich mit (sowohl auf der Client- und Server-Seite).

  • Verwendung verschiedener Medientypen (ein eindeutiger Medientyp pro Detaillierungsgrad), ausgewählt über die Kopfzeile Accept:.

    Ich möchte nicht wirklich diesen Weg gehen. Ich bin mir nicht sicher, ob die Medientypen für diesen Zweck geeignet sind und die Welt wahrscheinlich sowieso nicht mehr benutzerdefinierte Medientypen benötigt.

  • Verwendung des profile Relation/Medientyp-Parameters. Dies scheint ein wenig besser (keine zusätzlichen Medientypen sind erforderlich), aber ich bin immer noch unsicher, ob Medientypen die richtige Methode für die Auswahl des "Was" (Inhalt) einer Antwort sind. Sie scheinen eher geeignet zu sein, das "Wie" (Format) der Antwort zu spezifizieren.

  • Für Buchsammlungen (/books?publishedIn=1980s), nur eine kleine Teilmenge aller verfügbaren Daten zurückgegeben wird, was am wichtigsten ist ein href für jedes Buch, die abgefragt werden können, die vollständigen Daten über ein Buch zu bekommen.

    Dieser Ansatz hat mindestens zwei Probleme:

    1. Welche Attribute in Sammlung Antworten neben den href Links enthalten sind? Idealerweise gibt es gerade genug zusätzliche Daten, um die meisten Kunden zu befriedigen; sonst ...

    2. Die Kunden müssen viele zusätzliche Abfragen (eine pro Buch) durchführen, um alle Daten zu sammeln, die sie benötigen.

Es gibt möglicherweise mehr Strategien für den gewünschten Detaillierungsgrad auswählen. Ich bin interessiert zu erfahren, was in der Praxis gut funktioniert, ohne die REST-Fähigkeit zu sehr zu beeinträchtigen.

Antwort

1

Ich denke, es hängt hauptsächlich davon ab, wie viel Flexibilität Sie Ihren API-Clients geben möchten.

Wenn Sie die unterschiedliche Verwendung Ihrer Daten kennen, sollten Sie einige verfügbare Formate definieren, die Ihre API zurückgeben kann.

Zum Beispiel mit dieser Struktur:

GET /books (with a default format if nothing is specified) 
GET /books/minimal 
GET /books/full 
GET /books/otherformat 

Beachten Sie, dass diese auch diese URL-Struktur verwenden können, wenn Sie Ihre Endpunkte nicht duplizieren wollen:

GET /books?format=minimal 

jedoch entweder In diesem Fall müssen Sie genau wissen, welche Daten Ihre Kunden zu einem bestimmten Zeitpunkt benötigen oder wollen.

Ich würde mich nicht auf Medientypen verlassen, da dies für Benutzer verwirrender sein könnte als andere standardmäßige Methoden zum Arbeiten mit REST-APIs.

[EDIT]

Auch sollten Sie sich entscheiden, die gesamte Liste der Unholde angeben zurückzukehren und dass GET-Anfragen nicht ausreichend sind, erfahren Sie in diesem post für eine alternative Art und Weise beziehen könnte unter Verwendung von POST-Anfragen

+0

Ich habe in der Zwischenzeit GraphQL gefunden (http://Stackoverflow.com/a/41646020/240733)), das kommt dem sehr nahe, wonach ich gesucht habe. Allerdings akzeptiere ich Ihre Antwort, weil es einen gesunden Menschenverstand ergibt und wahrscheinlich viel einfacher zu implementieren ist. Vielen Dank! – stakx

0

Ich hatte noch nicht von Facebooks GraphQL gehört, als ich die obige Frage schrieb. Unter anderem löst es das Problem, welche Daten ein Dienst auf sehr allgemeine, flexible Weise zurückgeben sollte (was für statisch typisierte Sprachen wahrscheinlich nicht besonders geeignet ist, aber ideal für z. B. JavaScript ist).

Dies geschieht, indem der Client die "Form" des gewünschten Datengraphen in einem Metadatenformat angibt, das JSON ähnelt, aber anstelle von Schlüssel/Wert-Paaren nur Schlüssel bereitgestellt werden.

Ein Beispiel aus der Website:

# GraphQL query: 
{ 
    hero { 
    name 
    friends { 
     name 
    } 
    } 
} 

Für die oben stehende Abfrage, ein GraphQL Dienst könnte ein Objekt zurück, das die gleiche beschriebene Struktur hat:

{ 
    "data": { 
    "hero": { 
     "name": "R2-D2", 
     "friends": [ 
     { 
      "name": "Luke Skywalker" 
     }, 
     { 
      "name": "Han Solo" 
     }, 
     { 
      "name": "Leia Organa" 
     } 
     ] 
    } 
    } 
} 

Eine Sache, ich bin noch nicht ganz sicher ist, wie dies in einem REST-Service zusammen mit GET Anfragen (die keinen Anfragetext haben sollten) verwendet werden würde.