Tipo di restituzione dell'API del servizio Web

0

Sto cercando di trovare alcune opinioni sulle migliori pratiche per restituire diversi tipi di dati per lo stesso "endpoint". Sorprendentemente, non riesco a trovare molto su questo argomento.

Fondamentalmente, sto costruendo un'API per il nostro sito Web, che è un'app a pagina singola. Il client utilizza la memorizzazione nella cache per archiviare i dati tra le pagine e questi dati vengono aggiornati, se necessario, dal server (tramite websocket). Esistono diversi percorsi che restituiscono un elenco di dati. Ogni elemento nell'elenco può potenzialmente essere abbastanza grande e la lista stessa può contenere molti elementi.

Poiché il frontend utilizza già il caching, vogliamo ridurre la quantità di dati non necessari inviati al client, ove possibile. Un'opzione per realizzare ciò è fornire un modo per il frontend per ottenere un elenco degli ID delle risorse per una particolare richiesta. Sulla base di questo elenco, il client potrebbe quindi richiedere i dati di cui ha bisogno (ad esempio se si verifica un errore di cache).

Questo approccio è interessante, ma solleva diverse domande.

  • Cosa succede se il frontend sa già che non ha nessuna delle risorse? Invece di richiedere un elenco di ID, dovrebbe essere in grado di richiedere direttamente i dati.
  • Qual è l'approccio migliore? I possibili approcci e i loro (dis) vantaggi appaiono di seguito.

Domanda

Esiste un approccio non elencato di seguito che sembra appropriato? C'è un approccio che mi è mancato potrebbe essere migliore? Questo sembra eccessivo?

aproaches

  1. Invia i dati - Opzione Nucleare # 1.

    I vantaggi

    • Semplicità
    • Il tipo di reso è coerente

    Svantaggi

    • Il client potrebbe già avere molti dati, sprecando larghezza di banda
  2. Utilizza la stessa route e dichiara un parametro query che determina il tipo di dati da restituire - Sebbene non sia l'opzione peggiore, sembra sporca restituendo diversi tipi di dati dallo stesso endpoint (sì, So che puoi specificare Content-Type nelle richieste, ma questa intestazione dice al server quale rappresentazione dei dati è desiderata, non in realtà ciò che tipo di dati da restituire).

    I vantaggi

    • Il client può determinare quando vuole i dati o solo gli ID

    Svantaggi

    • Il tipo di reso dipende dal valore della query param
    • Aggiunta logica condizionale
  3. Consenti selezione campi. : questo approccio segue Suggerimento 7 su questo blog .

    I vantaggi

    Svantaggi

    • Aggiunta complessità non necessaria - La selezione del campo non ha senso per la nostra app. Pertanto, l'unico valore valido per questo parametro sarebbe il campo ID
    • Il formato dei dati dipende dalla query param - mentre il tipo di dati tecnicamente rimane lo stesso, la sua struttura è diversa in ogni richiesta. Non è qualcosa che mi piace davvero.
  4. Prependi la rotta originale con /ids - I client sarebbero in grado di inviare una richiesta GET allo stesso percorso che avrebbero per i dati effettivi aggiunti da /ids . Ad esempio, anziché /cars , la richiesta verrebbe inviata a /ids/cars .

    I vantaggi

    • Sembra più semanticamente significativo rispetto all'uso di un parametro di query

    Svantaggi

    • GET sarebbe l'unica richiesta logica che verrebbe mai inviata a questi endpoint
    • DRY o logica condizionale aggiunta - O deve essere aggiunto un nuovo endpoint che sostanzialmente duplica l'endpoint originale o lo stesso endpoint utilizzato con la stessa logica condizionale necessaria per il punto 2
  5. Utilizza un valore per Accept e Content-Type intestazioni simili a application/json+id - Questo è un approccio simile a quello utilizzato da LTI. I vantaggi e gli svantaggi (per quanto ne so) sono gli stessi del punto 2.

  6. Invia sempre solo l'ID - Opzione Nucleare # 2.

    I vantaggi

    • Semplicità
    • Il tipo di reso è coerente
    • Potenzialmente si ottengono meno dati inviati al client

    Svantaggi

    • Poiché il numero di risorse disponibili potrebbe essere elevato, questo potrebbe comportare molte richieste GET (oltre 200) se la cache è (quasi) vuota, vanificando in definitiva lo scopo di questo approccio
    • Semanticamente meno significativo - Sto facendo una richiesta per le risorse, non i loro ID!
posta c1moore 25.09.2017 - 02:28
fonte

2 risposte

1

Per qualcosa di simile, un approccio che ho usato su un progetto che funziona abbastanza bene è usare qualcosa come Falcor. Ad un livello molto alto, Falcor fornisce quanto segue:

  • Un'API grafico unificata per richiedere i dati specifici che intendi visualizzare
  • Memorizzazione nella cache centralizzata
  • Query server ottimizzate (cioè richiede solo ciò che manca localmente)

Per essere chiari, ci sono altri framework per le API grafiche, ma Falcor è quello con cui ho esperienza.

Falcor è diviso tra un componente lato client e un componente lato server.

  • Il lato client memorizza nella cache le informazioni locali e determina i delta da richiedere
  • Il lato server ha "percorsi" per estrarre dati da server API completi o implementare direttamente tutto
  • Il lato server può invalidare le voci della cache che aiutano l'utente a rimanere fresco

Tutto ciò che ho detto, in base alla mia esperienza, è che non si ottiene una flessibilità del genere senza alcun costo. Questo costo si presenta sotto forma di una curva di apprendimento ripida per capire esattamente cosa sta facendo per te. Il fatto che abbia un livello di strato dell'interfaccia utente e un livello di livello server cambia la modalità di progettazione dell'applicazione. In sostanza, invece di gestire da solo le tue cache, ti fidi dello strumento che lo fa per te.

Sono sicuro di aver solo scalfito la superficie e questo è solo uno dei modi per affrontare ciò che stai descrivendo. Ha una discreta integrazione con React in modo che i diversi componenti sullo schermo possano essere aggiornati secondo necessità. Cioè se il server invalida una voce che è in uso altrove sullo schermo, Falcor è abbastanza intelligente da comprimere i dati mancanti con la richiesta successiva.

Pro

  • Combina le opzioni 2 e 3 nella tua domanda
  • Gestisce il caching a tuo nome
  • L'interfaccia utente riceve solo i dati necessari per la visualizzazione

Contro

  • Ha una curva di apprendimento ripida (così come altri strumenti simili)
  • L'interfaccia della query grafica non è molto intuitiva
  • Aggiunge un altro livello alla tua app

Sarò onesto, non lo userei per una semplice applicazione. Tuttavia, se si stanno incorporando elementi da diversi microservizi sullo schermo contemporaneamente in una SPA, può essere uno strumento molto utile per ridurre al minimo il traffico tra client e server mantenendo allo stesso tempo aggiornata l'interfaccia utente.

    
risposta data 25.09.2017 - 18:17
fonte
0

C'è molto qui e probabilmente non coprirò ogni parte di ciò che hai menzionato nella domanda. Fondamentalmente hai un sacco di risorse e non vuoi ricaricarle tutte le volte. Ho lavorato a qualcosa del genere circa 12 anni fa, dove avevamo un'interfaccia mega-documento (ecco tutto) che abbiamo tirato giù dal server. È stato lento (ne parleremo più avanti) per gli utenti normali, ma abbiamo avuto persone sulle linee DSL che, nel tentativo di caricare una risposta, hanno impiegato qualcosa di pazzo come 15 minuti. Non volevamo riprogettare l'intera soluzione. Ho creato una cache client locale che conteneva tutti i dati condivisi. Il client dovrebbe quindi controllare ogni tipo di risorsa (non l'abbiamo chiamata ma è il termine corretto) e vedere se è stata aggiornata dal momento in cui è stata caricata sul client. Ciò ha ridotto la quantità di dati caricati e reso l'esperienza abbastanza tollerabile da non essere stata licenziata.

Prima di tutto, non penso ci sia alcun motivo per evitare di restituire rappresentazioni diverse degli stessi dati, anche se alcune sono meno dettagliate di altre. Il grafico falcor è, a mio avviso, un ottimo candidato per un tipo di supporto registrato ma non sembra essere uno. Nessuna questione importante, tuttavia, puoi sempre utilizzare albero x non registrato . L'utilizzo dell'intestazione Accept è il modo corretto per farlo. Ecco perché esistono tipi di media.

Il design a cui sembra che tu voglia andare è che nel caso in cui non hai nulla, vuoi tirare tutto in una volta sola. Se hai molti dati, come dici tu, probabilmente non vuoi farlo. Questo andrà molto peggio di ottenere l'elenco delle risorse e tirarle tutte. La ragione principale è che, in generale, per prima cosa fai questo messaggio gigante sul server, quindi devi tirare giù ogni byte singolo di quel mostro, e solo allora puoi iniziare a fare qualsiasi cosa con i dati . Ciò non solo significa un grande ritardo, ma sottolineerà anche il cliente in quanto ha bisogno di mantenere tutto ciò in memoria. Se sei impegnato su questa rotta, guarda un parser JSON in streaming come OboeJS .

Quello che farei, se fossi in te, è creare un grafico usando le specifiche del grafico JSON di Falcor (perché no?) e allega l'ultima timestamp di modifica a ciascuna risorsa che elencherai nel grafico. Quindi è sufficiente percorrere prima la larghezza dell'albero e recuperare tutto ciò che non si possiede o è più recente di quello che si ha. Funziona bene se la struttura del tuo albero ha la forma della struttura del tuo flusso di lavoro dell'interfaccia utente. Ad esempio, supponi che la tua pagina iniziale mostri un elenco di documenti. Assicurati di aver prima aperto l'elenco dei documenti. Quindi tornare indietro e ottenere il contenuto (se si desidera precaricare) di tali documenti. Se sei fortunato, lo tiri giù prima che facciano clic su di esso o lo stia già scaricando. In caso contrario, sposta la priorità di quell'elemento nel tuo recupero. Dal momento che hai solo bisogno di tirare l'una cosa, se non ci vuole molto tempo comunque.

I problemi che ho avuto oltre un decennio fa erano tutti il risultato del tentativo di abbattere tutto in una grande palla di fango. Il prossimo sistema è stato progettato per staccare ogni cosa separatamente. Le persone intelligenti mi hanno detto che sarebbe stato più lento o avrebbe avuto troppi sovraccarichi. I risultati sono stati inequivocabilmente che la palla di fango è una cattiva idea. I clienti odiavano la palla di fango. Hanno adorato il design che ha tirato ogni pezzo. Il motivo era che doveva aspettare la palla di fango. Il design gerarchico sembrava per lo più istantaneo. Non erano a conoscenza di ritardi nell'ottenere dati dal server.

    
risposta data 25.09.2017 - 20:07
fonte

Leggi altre domande sui tag