2016-07-01 36 views
8

Come è possibile utilizzare normalizr per gestire le risposte nidificate standardizzate JSON API chiave tramite lo standard { data: ... }?Redux normalizr - risposte API nidificate

Ad esempio, un Book

{ 
    data: { 
     title: 'Lord of the Rings', 
     pages: 9250, 
     publisher: { 
      data: { 
       name: 'HarperCollins LLC', 
       address: 'Big building next to the river', 
       city: 'Amsterdam' 
      }, 
     }, 
     author: { 
      data: { 
       name: 'J.R.R Tolkien', 
       country: 'UK', 
       age: 124, 
      } 
     } 
    } 
} 

Come dovrei disegnare schemi per affrontare la chiave di dati annidata?

+0

JSON, che si registra non segue le specifiche [ 'JSONAPI'] (http://jsonapi.org/format/ # documento-alto livello). Rapidamente, non puoi nidificare altre risorse nella principale, ma per includere altre risorse nel payload devi usare la chiave specifica ['include'] (http://jsonapi.org/format/#fetching-includes) . Nella risorsa principale è possibile inviare solo [un insieme limitato di informazioni] (http://jsonapi.org/format/#document-resource- object-relationships) sulle relazioni tra sé e altre risorse sotto la chiave 'relazioni'. – NickGnd

+0

Vostro diritto, aggiornerò la domanda – AndrewMcLagan

risposta

3

Credo che quello che stai cercando sia l'uso della funzione assignEntity che può essere passata nelle opzioni di normalize. In questo caso ci consente, se necessario, di filtrare le proprietà ridondanti data e passare direttamente ai valori sottostanti.

Effettiva assignEntity controlliamo come ogni chiave di dati viene normalizzata. Dai uno sguardo allo here per un po 'di più su come funziona.

Ho messo questo insieme come una dimostrazione, dare un'occhiata: http://requirebin.com/?gist=b7d89679202a202d72c7eee24f5408b6. Ecco un frammento:

book.define({ 
    data: { 
    publisher: publisher, 
    author: author, 
    characters: normalizr.arrayOf(character) 
    }} 
); 

publisher.define({ 
    data: { 
    country: country 
    } 
}); 

const result = normalizr.normalize(response, book, { assignEntity: function (output, key, value, input) { 
    if (key === 'data') { 
    Object.keys(value).forEach(function(d){ 
     output[d] = value[d]; 
    }) 
    } else { 
    output[key] = value; 
    } 
}}); 

anche vedere in particolare Ln 29, in cui la matrice di characters ha alcuni oggetti con l'informazione inserita all'interno data e alcuni senza. Tutti sono normalizzati correttamente.

Ho anche aggiunto alcune parti per mostrare come funziona con array e dati profondamente annidati, vedere il modello country all'interno di publisher.

Con i dati forniti è necessario uno slug a causa dell'assenza di id, che ogni schema contiene anche nell'esempio.

Normalizr è fantastico, mi auguro che aiuta a spiegare un po 'più su di esso :)

+0

Ottima risposta, fantastico esempio! – AndrewMcLagan

+0

Grazie! Fatemi sapere se pensate che qualsiasi parte possa trarre beneficio da ulteriori spiegazioni :) – horyd

+0

Ho intenzione di aggiornare la domanda con una risposta JSON-API corretta – AndrewMcLagan

6

Per ogni entità nella risposta, è necessario creare il proprio schema.

Nel tuo esempio, abbiamo tre soggetti - books, authors e publishers:

// schemas.js 
import { Schema } from 'normalizr'; 

const bookSchema = new Schema('book'); 
const publisherSchema = new Schema('publisher'); 
const authorSchema = new Schema('author'); 

Se qualche entità contiene dati nidificati che dovrebbe essere normalizzata, abbiamo bisogno di usare il metodo define di esso schema.This metodo accetta un oggetto con regole di annidamento.

Se abbiamo bisogno di normalizzare publisher e author puntelli di book entità, dovremmo passare un oggetto per define funzione con stessa struttura come la nostra risposta:

// schemas.js 
bookSchema.define({ 
    data: { 
    publisher: publisherSchema, 
    author: authorSchema 
    } 
}); 

Ora siamo in grado di normalizzare la nostra risposta:

import { normalize } from 'normalizr'; 
import { bookSchema } from './schemas.js'; 

const response = { 
    data: { 
     title: 'Lord of the Rings', 
     pages: 9250, 
     publisher: { 
      data: { 
       name: 'HarperCollins LLC', 
       address: 'Big building next to the river', 
       city: 'Amsterdam' 
      }, 
     }, 
     author: { 
      data: { 
       name: 'J.R.R Tolkien', 
       country: 'UK', 
       age: 124, 
      } 
     } 
    } 
} 

const data = normalize(response, bookSchema); 
+0

Ok, se poteste elaborare. Sembra fantastico. Vorrei una risposta ben spiegata per il resto della comunità. – AndrewMcLagan

+0

@AndrewMcLagan nessun problema :) Risposta aggiornata. – 1ven

+0

Cosa succede se (come sopra) l'oggetto risposta radice, 'book' in questo caso è anche nidificato con' {data} '? – AndrewMcLagan