Skip to content

Latest commit

 

History

History
131 lines (109 loc) · 3.9 KB

README_adding-queries.md

File metadata and controls

131 lines (109 loc) · 3.9 KB

Adding Queries

schema-driven

schema-driven (or schema-first development) is a process that should be followed when adding a new feature to the API:

  1. Extending the schema definition

    Extend the GraphQL schema definition with a new root field (and new data types, if needed):

    // -------------------
    // src/index.js
    // -------------------
    const typeDefs = `
    // 1
    type Query {
      info: String!
      // 2
      feed: [Link!]!
    }
    // 3
    type Link {
      id: ID!
      description: String!
      url: String!
    }
    `;
    • [1] - all queries should go inside type Query{}
    • [2] - feed root field is added to the Query type; will be used for retrieving the list of Link elements
    • [3] - Link data type represents the links that can be posted to the App
    • ! - indicates the field will never contain any elements that are null
  2. Implement resolver functions

    The next step is to implement the resolver function for the feed query, still on the same file:

    // 1
    let links = [
      {
        id: 'link-0',
        url: 'graphql.org'
        description: 'GraphQL is awesome!',
      }
    ];
    const resolvers = {
      // 2
      Query: {
        info: () => 'This is the API of a Hackernews Clone',
        // 3
        feed: () => links
      },
      // 4
      Link: {
        id: root => root.id,
        description: root => root.description,
        url: root => root.url
      }
    };
    • [1] - links variable stores the links at runtime. For now, it stored only in-memory rather than persisted in a database
    • [2] - all resolvers for Query should go inside Query:{}
    • [3] - resolver for the feed root field, named after its corresponding field from the schema definition
    • [4] - resolvers for the fields on the Link type. This can actually be removed, they are not needed because GraphQL server infers what they look like
  1. Testing the query

    Restart the server with CMD+C (to kill the server) and by running node src/index.js to start it again.

    Send the following feed query through the Playground:

    query {
      feed {
        id
        url
        description
      }
      info
    }

    Notice that you're also sending info query, as you can actually send multiple queries in one request. A sample server response would be:

    {
      "data": {
        "feed": [
          {
            "id": "link-0",
            "url": "graphql.org",
            "description": "GraphQL is awesome!"
          }
        ],
        "info": "This is the API of a Hackernews Clone"
      }
    }

The query resolution process

Every field inside schema definition is backed by one resolver function which is responsible for returning the precise data for that field. Server invokes all these resolver functions for the fields that are contained in the query, package up the response according to the query's shape.


All resolver functions always receive 4 arguments:

  • root (or parent) - the result of the previous resolver function
  • args - carries the arguments for the GraphQL operation
  • context - explained in the next section
  • info - learn about it from here and here

GraphQL queries can be nested, each level of nesting (ie: nested curly braces) corresponds to one resolver execution level. Consider the following query:

query {
  feed {
    id
    description
    url
  }
}

The first level invokes the feed resolver and returns the data stored in links. On the second level, the resolver for Link type for each element from the returned list gets invoked, hence the incoming root object on this level is the element inside the links list.