2015-12-10 5 views
27

Si supponga di avere un tipo GraphQL e include molti campi. Come interrogare tutti i campi senza scrivere una lunga query che include i nomi di tutti i campi?Come interrogare tutti i campi del tipo GraphQL senza scrivere una lunga query?

Per esempio, se ho questi campi:

public function fields() 
    { 
     return [ 
      'id' => [ 
       'type' => Type::nonNull(Type::string()), 
       'description' => 'The id of the user' 
      ], 
      'username' => [ 
       'type' => Type::string(), 
       'description' => 'The email of user' 
      ], 
      'count' => [ 
       'type' => Type::int(), 
       'description' => 'login count for the user' 
      ] 

     ]; 
    } 

per interrogare tutti i campi di solito la domanda è qualcosa di simile:

FetchUsers{users(id:"2"){id,username,count}} 

Ma voglio un modo per avere gli stessi risultati senza scrivere tutti i campi, qualcosa del genere:

FetchUsers{users(id:"2"){*}} 
//or 
FetchUsers{users(id:"2")} 

C'è un modo per farlo in GraphQ L ??

Sto usando Folkloreatelier/laravel-graphql libreria.

+1

Stai chiedendo come fare qualcosa che GraphQL, in base alla progettazione, non supporta. –

+2

Basta digitare quei 40 campi qualcosa e sperare che non si commetta un errore :) – Ska

+0

Wow, sto solo iniziando con GraphQL, e questo è un WTF serio. – user949300

risposta

22

Purtroppo quello che ci piace fare, non è possibile. GraphQL richiede che tu sia esplicito sulla specifica dei campi che desideri vengano restituiti dalla tua query.

+1

Ok, e se richiedo qualche oggetto di un modulo sconosciuto dal backend che dovrei proxy o inviare? – meandre

+5

@meandre, l'intera idea di graphql è che non esiste una "forma sconosciuta". –

+1

@meandre, la mia risposta qui sotto potrebbe esserti utile? –

15

Credo che l'unico modo per farlo è utilizzando frammenti riutilizzabili:

fragment UserFragment on Users { 
    id 
    username 
    count 
} 

FetchUsers { 
    users(id: "2") { 
     ...UserFragment 
    } 
} 
+5

Se lo facessi, dovrei scrivere comunque ogni nome di campo "almeno nel frammento", streghe cosa stavo cercando di evitare, sembra che GraphQL ci costringa ad essere espliciti. – BlackSigma

5

Ho affrontato lo stesso problema quando avevo bisogno di caricare i dati sulla posizione che avevo serializzato nel database dall'API di Google Places. In generale, vorrei che fosse tutto funzionante, quindi funziona con le mappe, ma non volevo dover specificare tutti i campi ogni volta.

Stavo lavorando in Ruby, quindi non posso darvi l'implementazione di PHP, ma il principio dovrebbe essere lo stesso.

Ho definito un tipo scalare personalizzato chiamato JSON che restituisce solo un oggetto JSON letterale.

L'implementazione rubino era in questo modo (usando graphql-ruby)

module Graph 
    module Types 
    JsonType = GraphQL::ScalarType.define do 
     name "JSON" 
     coerce_input -> (x) { x } 
     coerce_result -> (x) { x } 
    end 
    end 
end 

Poi l'ho usato per i nostri oggetti in questo modo

field :location, Types::JsonType 

vorrei utilizzare questo con molta parsimonia, però, usando solo dove sai che hai sempre bisogno dell'intero oggetto JSON (come ho fatto nel mio caso). Altrimenti sta sconfiggendo l'oggetto di GraphQL più in generale.

+1

Questo è esattamente ciò di cui avevo bisogno, grazie. Il mio caso d'uso è che ho delle stringhe traducibili dall'utente in tutto il sistema, e sono memorizzate come json nel db come "{" it ":" Ciao "," es ":" Hola "}'. E poiché ciascun utente può implementare il proprio sottoinsieme di lingue per il proprio caso d'uso, non ha senso che l'interfaccia utente interroghi ogni possibile sottoinsieme. Il tuo esempio funziona perfettamente. –

13

Sì, è possibile effettuare il utilizzando introspection. Fare una query GraphQL simili (per tipo UserType)

{ __type(name:"UserType") { 
    fields { 
     name 
     description 
     } 
    } 
} 

e si otterrà una risposta come (nomi di campo effettivo dipenderà dal vostro schema/definizione stessa tipo)

{ 
    "data": { 
    "__type": { 
     "fields": [ 
     { 
      "name": "id", 
      "description": "" 
     }, 
     { 
      "name": "username", 
      "description": "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only." 
     }, 
     { 
      "name": "firstName", 
     "description": "" 
     }, 
     { 
      "name": "lastName", 
      "description": "" 
     }, 
     { 
     "name": "email", 
      "description": "" 
     }, 
     (etc. etc. ...) 
     ] 
    } 
    } 
} 

Puoi quindi leggi questo elenco di campi nel tuo client e crea dinamicamente una seconda query GraphQL per ottenere tutti questi campi.

Questo si basa sulla conoscenza del nome del tipo per il quale si desidera ottenere i campi: se non si conosce il tipo, ci sono altre query per visualizzare tutti i tipi nel link sopra.

NOTA: si tratta dei dati GraphQL over-the-wire: sei da solo per capire come leggere e scrivere con il tuo cliente reale.

Problemi correlati