Domanda

Sto lavorando alla frontendazione di un'applicazione di una singola pagina e devo elencare un numero di studenti. Ogni studente è collegato a un certo user_id, questo è ciò che l'API ritorna per tutti i ruoli utente (SuperAdmin, Admin, Professor, Student) quando eseguo 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
}
.

Sto lavorando al ruolo della Superdmin al momento in cui ho bisogno di dati extra da ciascun studente (subscription_type), che è disponibile solo su GET /users/:id

Quindi quando sto elencando 20-30 studenti su una pagina tramite GET /students/, per ottenere il subscription_type, dovrò anche fare 20-30 richieste extra, una per ogni studente.

Ho parlato con il ragazzo dell'API su questo e mi è stato detto che includendo i dati extra in students "non è il modo riposo di farlo", "rallenterà i tempi di risposta ancora di più" e che "30 richieste extra pesare meno di un grosso blocco ".

Non so nulla del lavoro su un'API, quindi non posso davvero dire, ma sono pazzo a pensare che 30 richieste su un carico di pagina sia ridicolo?

Allora cosa successivo? Vado avanti ed eseguo le richieste extra? Dovrebbe separare le risposte per ogni ruolo dell'utente e includere solo le cose di cui ho bisogno per ogni ruolo? Qual è il modo corretto di gestire questo?

È stato utile?

Soluzione

Mentre parlando rigorosamente il ragazzo dell'API è corretto, seguendo il Vangelo Respulto troppo rigorosamente può portare a inefficienze come il problema di 1 + N creato dall'implementazione purista. Un concetto chiave nel design riposante è che le risorse non devono mappare direttamente agli oggetti di dominio. Quando si progettano risorse, si deve guardare gli scenari di utilizzo. Nello scenario Super Admin, suona come quando il client richiede una raccolta di students e anche in genere o richiede sempre dati da users, in particolare subscription_type. Il modello dell'oggetto è chiaramente normalizzato come dovrebbe essere, ma ciò non dice che le risorse devono essere, o devono sempre essere.

Ci sono un paio di modelli diversi che ho usato per creare scenari simili più efficienti. Quale (se neanche) si applichi dipende da come le risorse vengono consumate dai clienti.

Resource composito

Questa è la combinazione di tutti o parte due o più oggetti di dominio (ad esempio student e user) in una singola risorsa.

Poiché tutti i students sono presumibilmente anche generacodicitagcode, è possibile includere tutto o parte dei dati dell'utente nella risorsa studente come appropriato.

users

{
  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"
}
.

Risorse correlate

(simile a un'altra risposta) Questa è una tecnica in cui il client può indicare che vuole una risorsa correlata inclusa nella risposta. Ciò è particolarmente utile in una relazione tipo "ha una" nel modello di dominio. Permette al client di essere essenzialmente lazy load o imager load la risorsa.

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

{
  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"
   ...
  }
}
.

Altri suggerimenti

Hai due problemi qui, che non dovrebbero essere legati insieme - Uno è il dato restituito per ciascun utente per l'indice chiamata (/ studenti) e l'altro è il processo di autorizzazione che dovrebbe determinare quali dati un determinato utente può essere esposto a.

Per quanto riguarda il problema dei dati - non penso che ci sia una regola specifica da seguire. Dipende totalmente dalle esigenze della tua app. Se il campo Subscription_type è solitamente inutile, è possibile considerare il passaggio di un parametro di query ('includere_extra_data= 1' ad esempio) per indicare che è necessario sulla richiesta specifica, dove per impostazione predefinita non verrà restituito.

Per quanto riguarda il problema di autorizzazione: questo dovrebbe essere totalmente disconnesso dai dati che richiede la richiesta. Il server dovrebbe essere in grado di determinare quali dati sono visibili all'utente in base all'ID utente. (Puoi controllare il cANCAN GEM] [1] come una possibile soluzione).

Quindi, combinando i due problemi, qualsiasi tipo di utente dovrebbe essere in grado di rendere la richiesta "/ studenti" con o senza la bandiera "include_extra_data". Se il server trova l'utente non autorizzato per visualizzare i dati extra, è possibile scegliere una delle 2 opzioni - restituire solo i dati che l'utente è autorizzato a vedere o restituire una risposta "401 non autorizzata".

Entrambi i modi sono validi e influenzano il modo in cui si tratta della risposta sull'applicazione del cliente. (Io, personalmente, preferisco il successivo, come è più descrittivo per il cliente).

Spero che questo aiuti :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top