Frage

Ich arbeite am Frontend einer einseitigen Anwendung und muss eine Reihe von Studenten auflisten.Jeder Schüler ist an eine bestimmte Sache gebunden user_id Dies ist, was die API für alle Benutzerrollen (Superadmin, Admin, Professor, Student) zurückgibt, wenn ich sie ausführe GET /students:

{
  address: null
  class_id: 184
  class_name: "I B"
  date_of_birth: null
  first_name: "first"
  gender: null
  grade: 1
  id: 192
  last_name: "last"
  nationality: null
  place_of_birth: null
  ranking_by_class: 0
  ranking_by_school: 0
  registration_number: null
  user_id: 238
}

Ich arbeite derzeit an der Superadministratorrolle und benötige zusätzliche Daten von jedem Schüler (subscription_type), das nur auf verfügbar ist GET /users/:id

Wenn ich also 20–30 Studenten auf einer Seite auflistee über GET /students/, um das zu bekommen subscription_type, Außerdem muss ich 20 bis 30 zusätzliche Anfragen bearbeiten, eine für jeden Schüler.

Ich habe mit dem API-Mitarbeiter darüber gesprochen und mir wurde gesagt, dass die zusätzlichen Daten in einbezogen werden sollen students „ist nicht die RESTful-Methode“, „es wird die Antwortzeiten noch mehr verlangsamen“ und dass „30 zusätzliche Anfragen weniger wiegen als ein großer Teil“.

Ich weiß nichts über die Arbeit an einer API und kann daher nicht wirklich mitreden, aber bin ich verrückt, wenn ich denke, dass 30 Anfragen beim Laden einer Seite lächerlich sind?

Was kommt also als Nächstes?Soll ich die zusätzlichen Anfragen ausführen?Sollte er die Antworten für jede Benutzerrolle trennen und nur die Dinge angeben, die ich für jede Rolle benötige?Was ist der der richtige Weg damit umzugehen?

War es hilfreich?

Lösung

Obwohl der API-Typ streng genommen Recht hat, kann eine zu strenge Befolgung des RESTful-Evangeliums zu Ineffizienzen wie dem 1+N-Problem führen, das durch die puristische Implementierung entsteht.Ein Schlüsselkonzept im RESTful-Design besteht darin, dass Ressourcen nicht direkt Domänenobjekten zugeordnet werden müssen.Beim Entwerfen von Ressourcen müssen die Nutzungsszenarien berücksichtigt werden.Im Super-Admin-Szenario klingt es so, als würde der Client eine Sammlung von anfordern students und es benötigt normalerweise oder immer auch Daten von users, konkret subscription_type.Das Objektmodell ist eindeutig so normalisiert, wie es sein sollte, aber das bedeutet nicht, dass die Ressourcen sein müssen oder immer sein müssen.

Es gibt verschiedene Muster, die ich verwendet habe, um ähnliche Szenarien effizienter zu gestalten.Welche (falls vorhanden) zutreffen, hängt davon ab, wie die Ressourcen von den Clients verbraucht werden.

Zusammengesetzte Ressource

Dies ist die Kombination aller oder eines Teils von zwei oder mehr Domänenobjekten (z. B. student Und user) in eine einzige Ressource.

Da alle students sind vermutlich auch users, können Sie je nach Bedarf alle oder einen Teil der Benutzerdaten in die Schülerressource aufnehmen.

GET /students

{
  address: null
  class_id: 184
  class_name: "I B"
  date_of_birth: null
  first_name: "first"
  gender: null
  grade: 1
  id: 192
  last_name: "last"
  nationality: null
  place_of_birth: null
  ranking_by_class: 0
  ranking_by_school: 0
  registration_number: null
  user_id: 238
  subscription_type: "foo"
}

Ähnliche Resourcen

(Ähnlich einer anderen Antwort) Dies ist eine Technik, bei der der Client angeben kann, dass er eine verwandte Ressource in die Antwort aufnehmen möchte.Dies ist besonders nützlich bei Beziehungen vom Typ „hat eine“ im Domänenmodell.Es ermöglicht dem Kunden im Wesentlichen faule Ladung oder eifrige Ladung die Ressource.

GET /students

{
  address: null
  class_id: 184
  class_name: "I B"
  date_of_birth: null
  first_name: "first"
  gender: null
  grade: 1
  id: 192
  last_name: "last"
  nationality: null
  place_of_birth: null
  ranking_by_class: 0
  ranking_by_school: 0
  registration_number: null
  user_id: 238
}

GET /students?include_user=true

{
  address: null
  class_id: 184
  class_name: "I B"
  date_of_birth: null
  first_name: "first"
  gender: null
  grade: 1
  id: 192
  last_name: "last"
  nationality: null
  place_of_birth: null
  ranking_by_class: 0
  ranking_by_school: 0
  registration_number: null
  user_id: 238
  user:
  {
   id: 238
   subscription_type: "foo"
   ...
  }
}

Andere Tipps

Sie haben hier zwei Probleme, die nicht miteinander verbunden werden sollten - eine sind die Daten, die für jeden Benutzer für den Indexaufruf (/Schüler) zurückgegeben wurden, und der andere ist der Autorisierungsprozess, der feststellen sollte, welchen Daten ein bestimmter Benutzer ausgesetzt sein kann .

Was das Datenproblem angeht: Ich glaube nicht, dass es eine bestimmte Regel gibt, die befolgt werden muss.Es hängt ganz von den Anforderungen Ihrer App ab.Wenn das Feld subscription_type normalerweise nicht erforderlich ist, können Sie erwägen, einen Abfrageparameter zu übergeben (z. B. „include_extra_data=1“), um anzugeben, dass Sie es für die spezifische Anfrage benötigen, wo es standardmäßig nicht zurückgegeben wird.

Bezüglich der Autorisierungsfrage: Diese sollte völlig unabhängig von den Daten sein, die Sie in Ihrer Anfrage erfragen.Der Server sollte anhand der Benutzer-ID ermitteln können, welche Daten für den Benutzer sichtbar sind.(Sie können sich das ansehen CanCan-Juwel][1] als mögliche Lösung).

Durch die Kombination dieser beiden Probleme sollte jeder Benutzertyp in der Lage sein, die „/students“-Anfrage mit oder ohne das Flag „include_extra_data“ zu stellen.Wenn der Server feststellt, dass der Benutzer nicht berechtigt ist, die zusätzlichen Daten anzuzeigen, können Sie eine von zwei Optionen wählen: Entweder nur die Daten zurückgeben, die der Benutzer sehen darf, oder eine „401-Unberechtigte“-Antwort zurückgeben.

Beide Möglichkeiten sind gültig und beeinflussen die Art und Weise, wie Sie mit der Antwort in Ihrer Client-App umgehen.(Ich persönlich bevorzuge Letzteres, da es für den Kunden aussagekräftiger ist.)

Hoffe das hilft :)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top