2015-11-20 18 views
10

Ich schaue auf graphql. Ist es möglich, ein Objekt mit beliebigen Attributen zu definieren? Sagen wir, ich habe einige Daten wie:Dynamische (eindeutige) Objekte in GraphQl

editOptions : { boxes : 3 , size : { width: 23,height:32} , color: #434343 }, etc...} 

und dies ist in:

{ ... , box : { editOptions : {...} }, ... } 

Lassen Sie uns sagen, dass EditOptions nie mit der gleichen Struktur ist, manchmal nicht sinnvoll sein, um die Farbe zu haben, nur zum Beispiel Sakes. In Mungo kann man nur den Typ so etwas wie definieren:

EditOptions: {}

Diese EditOptions in der Regel einzigartig für jede Box. Mit einigen Attributen geteilt werden, aber die meisten sind einzigartig.

Also meine Frage ist, gibt es eine Möglichkeit, dies zu tun? oder ist das schlechte Übung und ich sollte meine Modelle ändern.

Vielen Dank.

Antwort

3

Sie haben zwei Möglichkeiten.

1. Schnittstelle

Wenn die editOptions basierend auf der Art variieren, sind aber für diese bestimmte Art konsistent, können Sie eine Interface (node.js example) verwenden.

Nehmen wir an, Sie haben zwei Objekte, eine Box und eine Kugel. Sie können ein Objekt Schnittstelle definieren, die beide implementieren:

interface Object 
type Box implements Object { 
    editOptions: BoxOptions 
} 
type BoxOptions { 
    boxes: Int, 
    size: ..., 
    color: ... 
} 
type Sphere implements Object { 
    editOptions: SphereOptions 
} 
type SphereOptions { 
    spheres: Int, 
    ... 
} 
type Query { 
    objects: [Object] 
} 

In Ihrer Anfrage, würden Sie dann eine Object zurückkehren, und die für jeden Typ auf Basis der gewählten Optionen:

query Query { 
    objects(filter: "...") { 
    ... on Box { 
     editOptions { 
     boxes 
     size 
     } 
    } 
    ... on Sphere { 
     editOptions { 
     spheres 
     } 
    } 
    } 
} 

In der zurückgegebenen JSON, Felder haben boxes und size Felder unter editOptions, und Kugeln haben spheres.

manchmal nicht sinnvoll sein, die Farbe

für einige der Boxen Sie die Farbe nicht, wenn zu haben, würde das Feld einfach leer sein (aber existiert noch im Schema).

2. JSON

Wenn die editOptions wirklich variabel sein kann, können Sie einfach das Feld als String definieren und serialisierte JSON senden über. Sie verlieren alle Typvalidierungen, aber die Struktur kann für jedes Objekt völlig willkürlich sein. Stellen Sie einfach sicher, dass Ihr Kunde versteht, was damit zu tun ist.

+0

Hey, sorry für die späte Antwort, das ist eine gute Lösung in der Tat es Ihnen danken. Das Problem ist, dass es nicht genau wie Box, Kugel, Würfel usw. Wir müssen es offen für unendliche Möglichkeiten machen =) aber das ist definitiv eine Möglichkeit. Danke! –

7

Verwenden GraphQLScalarType, einfach implementieren es mag:

import { GraphQLScalarType } from 'graphql/type'; 
import { GraphQLError } from 'graphql/error'; 
import { Kind } from 'graphql/language'; 

const ObjectType = new GraphQLScalarType({ 
    name: 'ObjectType', 
    serialize: value => value, 
    parseValue: value => value, 
    parseLiteral: (ast) => { 
    if (ast.kind !== Kind.OBJECT) { 
     throw new GraphQLError(
     `Query error: Can only parse object but got a: ${ast.kind}`, 
     [ast], 
    ); 
    } 
    return ast.value; 
    }, 
}); 

const ReturnType = new GraphQLObjectType({ 
    name: 'ReturnType', 
    fields: { 
    // ... 
    editOptions: { type: ObjectType }, 
    // ... 
    }, 
}); 
+0

Ich versuche, dies zu verwenden, aber ich bekomme diese Nachricht: '" Nachricht ":" Argument \ "data \" hat ungültigen Wert {a: \ "A \", b: \ "B \"}. \ NExpected type \ "ObjectType \", gefunden {a: \ "A \", b: \ "B \"}. "'. Irgendwelche Ideen wo ist das Problem? –

+1

Scheint, dass Sie dies jetzt als öffentliches Modul unter https://www.npmjs.com/package/graphql-type-json finden können. – jiku