Object Types

In many cases returning a scalar values like Int or String might not be enough and we might want to return more complex data, like Objects. Let’s modify our previous example to do this.

Adding type object into GraphQL’s schema.

Objects could be defined in the schema the same way as we defined the Query (lines 4-7) and then we could modify greetingUser Query to return our new object: greeting instead of String 

...
var schema = buildSchema(`

  type greeting {
    userName: String
    userRollDice(userName: String): String
  }

  type Query {
    greetingUser(userName:String!): greeting
  }
`);
...

Once we have the new greeting type into the schema we could write the resolver, which could be a plain Java Script object object (in our case a function that returns the exposed methods):

...
var greeting = (userName) => {

  function rollDice() {
    return Math.floor(Math.random() * 6) + 1;
  }  
    
  function userRollDice(args) {
    return `User ${args.userName} rolled: ${rollDice()}`;
  }
  return  {
    userName: userName,
    userRollDice: userRollDice
  }
}
...

what we just did:
– we created a new method called greeting which exposes one string property named userName, that we are passing and one method called userRollDice which will return String which will describe (in plain text) what dice # the used rolled.
– we also added a helper method called rollDice which will return a random number.

The whole code should look like this:

./server.js

var express = require('express');
var graphqlHTTP = require('express-graphql');
var { buildSchema } = require('graphql');
// Construct a schema, using GraphQL schema language

var schema = buildSchema(`

  type greeting {
    userName: String
    userRollDice(userName: String): String
  }

  type Query {
    greetingUser(userName:String!): greeting
  }
`);

var greeting = (userName) => {
  
  function rollDice() {
    return Math.floor(Math.random() * 6) + 1;
  }  
    
  function userRollDice(args) {
    return `User ${args.userName} rolled: ${rollDice()}`;
  }
  return  {
    userName: userName,
    userRollDice: userRollDice
  }
}


// The root provides a resolver function for each API endpoint
var root = {
  greetingUser: (args) => {
    return greeting(args.userName);
  }
};

var app = express();
app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true,
}));
app.listen(4001);
console.log('Running a GraphQL API server at localhost:4000/graphql');

Let’s give it a try. Using the Document explorer click on Query and you will see that there is a query named greetingUser, that expects userName string, and returns the new method greeting.

greetingUser(userNameString!): greeting

Explore the greeting and you will see that it could be queried for userName and userRollDice which also expects one string parameter.

userRollDice(userNameString): String
Having this information we are ready to construct our new query. Add the code below in GraphQL UI’s query box (up left)
query queryLabel($userName: String!) {
  greetingUser(userName: $userName){
    userName
    userRollDice(userName: $userName)
  }
}

and leave the parameter box (down left) the same for now.

{
  "userName": "Sam Smith"
}

Hitting play will produce a nice response like this:

{
  "data": {
    "greetingUser": {
      "userName": "Sam Smith",
      "userRollDice": "User Sam Smith rolled: 4"
    }
  }
}

GraphQL just returned us the greeting object that we requested.

Using ES6 features.

Let’s modify the resolver to use ES6 class syntax and also let’s add a destructors to clean up the code a bit.

./server.js

var express = require('express');
var graphqlHTTP = require('express-graphql');
var { buildSchema } = require('graphql');
// Construct a schema, using GraphQL schema language

var schema = buildSchema(`

  type greeting {
    userName: String
    userRollDice(userName: String): String
  }

  type Query {
    greetingUser(userName:String!): greeting
  }
`);

class greeting {
  
  constructor(userName) {
    this.userName = userName;
  }
  
  rollDice() {
    return Math.floor(Math.random() * 6) + 1;
  }  
    
  userRollDice({userName}) {
    return `User ${userName} rolled: ${this.rollDice()}`;
  }
}


// The root provides a resolver function for each API endpoint
var root = {
  greetingUser: ({userName}) => {
    return new greeting(userName);
  }
};

var app = express();
app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true,
}));
app.listen(4001);
console.log('Running a GraphQL API server at localhost:4000/graphql');

 what we just did:
– we replaced the JavaScript function resolver with class having the same methods.
– in userRollDice method we replaced args.userName with the destructor {userName}
– in the root resolver we call greetingUser, passing the userName and returning new instance of greeting

Leave a Reply