Graphql-js: Need guide for writing function to resolve root data type with nested type

Created on 16 Aug 2017  路  6Comments  路  Source: graphql/graphql-js

Hi all

Please guide how to resolve data with nested type

Query

query {
  article {
    content
    author {
      name
    }
  }
}

Server

const express = require('express')
const fs = require('fs')
const graphQLHTTP = require('express-graphql')
const { buildSchema } = require('graphql')

const app = express()

const schema = buildSchema(`
    type Article {
        content: String
        author: Author
    }

    type Author {
        name: String
    }

    type Query {
        article: Article
    }
`)

const resolver = {
    article() {
        // data in database is kept with ID as primary key, so how to get the next function to be executed to get related data
        return { content: 'Hello World', authorId: 1 }
    },
    author() {
        // this function never get executed, please guide how
        return { name: 'Steve' }
    }
}

app.use(graphQLHTTP({
    schema,
    rootValue: resolver,
    graphiql: true
}))

app.listen(3000)

Thanks

Most helpful comment

@jeud @kazahara @mrdulin Sorry for delay. Here is how it you should implement such APIs:

const express = require('express')
const fs = require('fs')
const graphQLHTTP = require('express-graphql')
const { buildSchema } = require('graphql')

const app = express()

const schema = buildSchema(`
    type Article {
        content: String
        author: Author
    }

    type Author {
        name: String
    }

    type Query {
        article: Article
    }
`)

const resolver = {
    article() {
        return new Article({ content: 'Hello World', authorId: 1 })
    },
}

class Article {
  constructor(data) {
    this.content = data.content;
    this._authorId = data.authorId;
  }

  author() {
    // const data = getAuthorDataFromDB(this._authorId);
    const data = { name: 'Steve' };
    return new Author(data);
  }
}

class Author {
  constructor(data) {
    this.name = data.name;
  }
}

app.use(graphQLHTTP({
    schema,
    rootValue: resolver,
    graphiql: true
}))

app.listen(3000)

Here are the official docs with another example: http://graphql.org/graphql-js/object-types/

All 6 comments

__authorID__ on your object won't be resolved because you didn't define __authorID__ on __type Article__.


I have not found a working thing but I found that I can pass a function on author property which returns an object.

const resolver = {
  article () {
// data in database is kept with ID as primary key, so how to get the next function to be executed to get related data
    return {
      content: 'Hello World',
      author: () => ({
        name: 'Steve'
      })
    }
  }
}

This returns the object which resolves to __type Author__. The only problem here is that I can't find ___author___ from __type Article__. I've tried some things but to no avail.

Any help on this particular issue?

Also, the arguments of the resolver function is not documented. Resolver functions have three arguments: args(Object type), context(Object type) and fieldDef.

same issue.

@jeud @kazahara @mrdulin Sorry for delay. Here is how it you should implement such APIs:

const express = require('express')
const fs = require('fs')
const graphQLHTTP = require('express-graphql')
const { buildSchema } = require('graphql')

const app = express()

const schema = buildSchema(`
    type Article {
        content: String
        author: Author
    }

    type Author {
        name: String
    }

    type Query {
        article: Article
    }
`)

const resolver = {
    article() {
        return new Article({ content: 'Hello World', authorId: 1 })
    },
}

class Article {
  constructor(data) {
    this.content = data.content;
    this._authorId = data.authorId;
  }

  author() {
    // const data = getAuthorDataFromDB(this._authorId);
    const data = { name: 'Steve' };
    return new Author(data);
  }
}

class Author {
  constructor(data) {
    this.name = data.name;
  }
}

app.use(graphQLHTTP({
    schema,
    rootValue: resolver,
    graphiql: true
}))

app.listen(3000)

Here are the official docs with another example: http://graphql.org/graphql-js/object-types/

@IvanGoncharov thanks. Does this way lead N+1 problem?

What about these type definition?

  1. self ref type:
type Person {
  id: ID!
  name: String
  friends: [Person]!
}

type Query {
  person(id: ID!): Person
}
  1. circle ref type:
type User {
  id: ID!
  name: String
  post: [Post]!
}

type Post {
  id: ID!
  title: String
  author: User!
}

type Query {
  user(id: ID!): User
  postsByUserId(id: ID!): [Post]!
  postById(id: ID!): Post
}
  1. ...
  2. ...

How can I write rootValue for these two types? Is there common guide for this? I don't want to list every case and ask you. Thanks

Without graphql-tools and constructor type definition

@mrdulin This repo issues are reserved for reporting bugs and asking for features.
https://github.com/graphql/graphql-js/blob/master/.github/ISSUE_TEMPLATE.md#questions-regarding-how-to-use-graphql

Was this page helpful?
0 / 5 - 0 ratings

Related issues

matthewgertner picture matthewgertner  路  4Comments

adriano-di-giovanni picture adriano-di-giovanni  路  3Comments

ablbol picture ablbol  路  4Comments

pranshuchittora picture pranshuchittora  路  3Comments

rafgraph picture rafgraph  路  4Comments