2017-12-18 4 views
1

Ich bin ziemlich neu zu GraphQL und ich versuche, ein Problem zu lösen, das mein Manager mir präsentiert hat.Erstellen einer verschachtelten Struktur in graphql

Ich habe die folgende Datenstruktur mir zur Verfügung gestellt, über eine 3rd-Party-API (die ich null Kontrolle haben):

[ 
    { 
    "id": 19, 
    "date": "2016-10-24T13:59:19", 
    "date_gmt": "2016-10-24T12:59:19", 
    "slug: "data", 
    "provider": { 
     "name": "data", 
     "logo": "data", 
     "destination_url": "data", 
     "coupon_label": "data", 
     "coupon_text": "data", 
     "coupon_code": "data", 
     "coupon_url": "data", 
    } 
    } 
] 

Ich brauche es in ein GraphQL Schema zu drehen, die wie folgt aussieht query:

{ 
    provider(slug: "slug") { 
    id 
    date 
    slug 
    name 
    logo 
    url 
    coupon { 
     label 
     text 
     code 
     url 
    } 
    } 
} 

ich habe es geschafft, unten mit dem Code sortieren die meisten davon aus, aber ich kann nicht herausfinden, wie sich die Coupon-Knoten in einer Gruppe zu.

Ich rate, dass dies ein weiterer benutzerdefinierter Typ sein muss? Wenn dies der Fall ist, scheint dies ineffizient zu sein, da ein Gutschein niemals außerhalb des Anbietertyps verwendet wird. Daher wollte ich wissen, ob es eine "Best Practice" -Methode gibt, die mir nicht bekannt ist.

import { GraphQLObjectType, GraphQLInt, GraphQLString } from 'graphql' 

const ProviderType = new GraphQLObjectType({ 
    name: 'Provider', 
    fields:() => ({ 
    id: { 
     type: GraphQLInt, 
     description: 'The primary key for the provider' 
    }, 
    slug: { 
     type: GraphQLString, 
     description: 'A unique string for the provider' 
    }, 
    status: { 
     type: GraphQLString, 
     description: 'The the published status of the provider' 
    }, 
    name: { 
     type: GraphQLString, 
     description: 'The name of the provider', 
     resolve (parent) { return parent.provider.name } 
    }, 
    logo: { 
     type: GraphQLString, 
     description: 'The full url of the provider logo', 
     resolve (parent) { return parent.provider.logo } 
    }, 
    url: { 
     type: GraphQLString, 
     description: 'The full url of the provider', 
     resolve (parent) { return parent.provider.destination_url } 
    }, 
    }) 
}) 

export default ProviderType 

Update:

Ich habe den Code wie folgt aktualisiert, aber es funktioniert immer noch nicht, so meine Annahme falsch gewesen sein muss (oder ich implementiert es falsch)

const ProviderType = new GraphQLObjectType({ 
    name: 'Provider', 
    fields:() => ({ 
    id: { 
     type: GraphQLInt, 
     description: 'The primary key for the provider' 
    }, 
    slug: { 
     type: GraphQLString, 
     description: 'A unique string for the provider' 
    }, 
    status: { 
     type: GraphQLString, 
     description: 'The the published status of the provider' 
    }, 
    name: { 
     type: GraphQLString, 
     description: 'The name of the provider', 
     resolve (parent) { return parent.provider.name } 
    }, 
    logo: { 
     type: GraphQLString, 
     description: 'The full url of the provider logo', 
     resolve (parent) { return parent.provider.logo } 
    }, 
    url: { 
     type: GraphQLString, 
     description: 'The full url of the provider', 
     resolve (parent) { return parent.provider.destination_url } 
    }, 
    coupon: { 
     type: CouponType, 
     description: 'The coupon information for the provider' 
    } 
    }) 
}) 

const CouponType = new GraphQLObjectType({ 
    name: 'Coupon', 
    fields:() => ({ 
    label: { 
     type: GraphQLString, 
     description: 'The label for the coupon', 
     resolve (parent) { return parent.provider.coupon_label } 
    }, 
    text: { 
     type: GraphQLString, 
     description: 'The text for the coupon', 
     resolve (parent) { return parent.provider.coupon_text } 
    }, 
    code: { 
     type: GraphQLString, 
     description: 'The code for the coupon', 
     resolve (parent) { return parent.provider.coupon_code } 
    }, 
    url: { 
     type: GraphQLString, 
     description: 'The url for the coupon', 
     resolve (parent) { return parent.provider.coupon_url } 
    } 
    }) 
}) 
+1

Sie benötigen einen Resolver in Ihrem Coupon-Feld in Ihrem Anbietertyp zurückkehren würden, da es ein verschachteltes/Unterfeld – vbranden

Antwort

3

Ihr Schema ist größtenteils korrekt, aber Sie benötigen einen Resolver für Ihr Gutscheinfeld im Anbieter, da es sich um einen verschachtelten Typ handelt. Siehe Launchpad Beispiel für interaktive Abfrage https://launchpad.graphql.com/r995kzj5kn

und hier ist der Code. Ich habe Ihre Beschreibungen der Kürze halber entnommen und einige Testdaten

import { 
    GraphQLObjectType, 
    GraphQLSchema, 
    GraphQLString, 
    GraphQLInt, 
    GraphQLList 
} from 'graphql' 

const data = [ 
    { 
    "id": 19, 
    "date": "2016-10-24T13:59:19", 
    "date_gmt": "2016-10-24T12:59:19", 
    "slug": "slug", 
    "provider": { 
     "name": "provider.name", 
     "logo": "provider.logo", 
     "destination_url": "provider.destination_url", 
     "coupon_label": "provider.coupon_label", 
     "coupon_text": "provider.coupon_text", 
     "coupon_code": "provider.coupon_code", 
     "coupon_url": "provider.coupon_url", 
    } 
    }, 
    { 
    "id": 20, 
    "date": "2016-10-24T13:59:19", 
    "date_gmt": "2016-10-24T12:59:19", 
    "slug": "slugplug", 
    "provider": { 
     "name": "provider.name", 
     "logo": "provider.logo", 
     "destination_url": "provider.destination_url", 
     "coupon_label": "provider.coupon_label", 
     "coupon_text": "provider.coupon_text", 
     "coupon_code": "provider.coupon_code", 
     "coupon_url": "provider.coupon_url", 
    } 
    } 
] 

const CouponType = new GraphQLObjectType({ 
    name: 'Coupon', 
    fields:() => ({ 
    label: { 
     type: GraphQLString, 
     resolve (parent) { return parent.provider.coupon_label } 
    }, 
    text: { 
     type: GraphQLString, 
     resolve (parent) { return parent.provider.coupon_text } 
    }, 
    code: { 
     type: GraphQLString, 
     resolve (parent) { return parent.provider.coupon_code } 
    }, 
    url: { 
     type: GraphQLString, 
     resolve (parent) { return parent.provider.coupon_url } 
    } 
    }) 
}) 

const ProviderType = new GraphQLObjectType({ 
    name: 'Provider', 
    fields:() => ({ 
    id: { type: GraphQLInt }, 
    date: { type: GraphQLString }, 
    slug: { type: GraphQLString }, 
    status: { type: GraphQLString }, 
    name: { 
     type: GraphQLString, 
     resolve (parent) { return parent.provider.name } 
    }, 
    logo: { 
     type: GraphQLString, 
     resolve (parent) { return parent.provider.logo } 
    }, 
    url: { 
     type: GraphQLString, 
     resolve (parent) { return parent.provider.destination_url } 
    }, 
    coupon: { 
     type: CouponType, 
     resolve(parent) { 
     return parent 
     } 
    } 
    }) 
}) 

const Query = new GraphQLObjectType({ 
    name: 'Query', 
    fields: { 
    provider: { 
     type: new GraphQLList(ProviderType), 
     args: { 
     slug: { type: GraphQLString } 
     }, 
     resolve (source, args) { 
     return args.slug ? 
      data.filter(({ slug }) => slug === args.slug) : 
      data 
     } 
    } 
    } 
}) 

const schema = new GraphQLSchema({ 
    query: Query 
}); 

abwechselnd können Sie nur die Ergebnisse in der Wurzel Resolver ändern, bevor sie nach unten wie die folgenden zu senden. dies erlaubt es dir, mit Ausnahme von coupon auf Anbietern alle Resolver von Ihren Typen zu entfernen, die nur parent.coupon

const Query = new GraphQLObjectType({ 
    name: 'Query', 
    fields: { 
    provider: { 
     type: new GraphQLList(ProviderType), 
     args: { 
     slug: { type: GraphQLString } 
     }, 
     resolve (source, args) { 
     const filtered = args.slug ? 
      data.filter(({ slug }) => slug === args.slug) : 
      data 
     return filtered.map(doc => { 
      return { 
      id: doc.id, 
      date: doc.date, 
      slug: doc.slug, 
      name: doc.provider.name, 
      logo: doc.provider.logo, 
      url: doc.provider.coupon_url, 
      coupon: { 
       label: doc.provider.coupon_label, 
       text: doc.provider.coupon_text, 
       code: doc.provider.coupon_code, 
       url: doc.provider.coupon_url 
      } 
      } 
     }) 
     } 
    } 
    } 
}) 
+0

Dank ist! Das ist eine wirklich umfassende Antwort! :) –

Verwandte Themen