2017-10-04 1 views
1

meines graphql Server Lassen Sie sagen, möchte die folgenden Daten als JSON holen, wo person3 und person5 einige ids sind:Apollo/GraphQL Feldtyp für Objekt mit dynamischen Tasten

"persons": { 
    "person3": { 
    "id": "person3", 
    "name": "Mike" 
    }, 
    "person5": { 
    "id": "person5", 
    "name": "Lisa" 
    } 
} 

Frage: Wie das Schema erstellen Typdefinition mit Apollo?

Die Schlüssel person3 und person5 werden hier abhängig von meiner Abfrage dynamisch generiert (d. H. area in der Abfrage verwendet). Also zu einer anderen Zeit könnte ich person1, person2, zurückgegeben bekommen. Wie Sie sehen persons ist kein Iterable, so wird folgendes als graphql Typdefinition ich mit apollo hat nicht funktioniert:

type Person { 
    id: String 
    name: String 
} 
type Query { 
    persons(area: String): [Person] 
} 

Die Schlüssel im persons Objekt kann immer unterschiedlich sein.

Eine Lösung wäre natürlich die Umwandlung der eingehenden JSON-Daten in ein Array für persons, aber gibt es keine Möglichkeit, mit den Daten als solche zu arbeiten?

+0

Kannst du klarstellen, was du meinst, wenn 'b' und' g' 'abhängig von meiner Suchanfrage' dynamisch generiert werden? Ist die Anwesenheit des einen oder anderen von den Feldern in der Anfrage abhängig? –

+0

@DanielRearden So 'b' und' g' sind IDs. Vielleicht sollte ich das in der Frage klarer machen. Die Abfrage enthält Optionen, um nur eine Untergruppe von Personen zu erhalten. Für eine Abfrage enthält die Antwort also Personen mit den IDs "a", "b", "c" und für eine andere Abfrage, zum Beispiel "b" und "g" die Frage. – Andru

+0

@DanielRearden Ich habe nun 'b' in' person3' und 'g' in' person5' geändert und etwas Text und eine Variable hinzugefügt, um es klarer zu machen. Die Abfrage enthält Optionen, um nur eine Untergruppe von Personen zu erhalten, wie im Text beschrieben. – Andru

Antwort

3

GraphQL setzt voraus, dass sowohl der Server als auch der Client im Voraus wissen, welche Felder für jeden Typ verfügbar sind. In einigen Fällen kann der Client diese Felder entdecken (über Introspektion), aber für den Server müssen sie immer im Voraus bekannt sein. Also irgendwie dynamisch diese Felder basierend auf den zurückgegebenen Daten zu generieren ist nicht wirklich möglich.

Sie könnte verwenden eine benutzerdefinierte JSON scalar und zurück, dass für Ihre Anfrage:

type Query { 
    persons(area: String): JSON 
} 

von JSON verwendet wird, umgehen Sie die Anforderung für die zurückgegebenen Daten eine bestimmte Struktur zu passen, so dass Sie zurückschicken können, was Sie wollen, solange es richtig formatiert JSON ist.

Natürlich gibt es erhebliche Nachteile dabei. Beispielsweise verlieren Sie das Sicherheitsnetz, das von den Typen bereitgestellt wird, die Sie zuvor verwendet hätten (buchstäblich jede Struktur könnte zurückgegeben werden, und wenn Sie die falsche zurückgeben, werden Sie nichts darüber erfahren, bis der Client es versucht um es zu benutzen und versagt). Außerdem verlieren Sie die Möglichkeit, Resolver für alle Felder innerhalb der zurückgegebenen Daten zu verwenden.

Aber ... Ihre Beerdigung :)

Als beiseite, ich hielte die Daten in ein Array Verflachung (wie Sie in Ihrer Frage vorgeschlagen), bevor es zurück an den Client sendet. Wenn Sie den Client-Code schreiben und mit einer dynamisch großen Liste von Kunden arbeiten, ist es wahrscheinlich viel einfacher, mit einem Array zu arbeiten, als mit einem Objekt, das mit der ID codiert ist. Wenn Sie beispielsweise React verwenden und für jeden Kunden eine Komponente anzeigen, konvertieren Sie das Objekt letztendlich in ein Array, um es trotzdem zuzuordnen. Bei der Gestaltung Ihrer API würde ich die Benutzerfreundlichkeit des Clients höher bewerten als die Vermeidung zusätzlicher Datenverarbeitung.

+0

Danke für Ihre Kommentare! Ich transformiere die eingehenden Daten vom Server. FYI: Der Grund für Objekte mit IDs war das schnellere Abrufen auf der Clientseite, da es sich nur um eine Suche nach einer ID handelt, um auf eine bestimmte Person zuzugreifen. – Andru

+0

Meine Situation gibt Validierungsfehler über eine Rails/GraphQL API zurück. Ich weiß nicht im Voraus, welche Schlüssel Fehler haben werden, daher verwende ich einen benutzerdefinierten JSON-Skalar. –

+0

Tatsächlich habe ich meinen Ansatz geändert, verschachtelte Arrays zu verwenden, die es mir erlaubten, die fehlerhaften Felder konsistent zurückzugeben. –

Verwandte Themen