Skip to content

Latest commit

 

History

History

graphql-language

GraphQL

Learning the GraphQL.

Quick notes

Each type in schema should have a corresponding field definition in resolver. Those Scalar type could be omitted unless you want to do some introspection.

## in schema
type Parent {
  name: String!
  children: [Child!]
}

type Child {
  name: String!
  toys: [Toy]
}

type Toy {
  name: String!
  createdAt: Date
}

type Query {
  parent(name: String!): Parent
  child(name: String!): Child
  toy(name: String!): Toy
}
// in reslovers
module.exports = {
  // Query is defined in the top type level
  Query: {
    // there is a field `parent` in the type Query
    parent: (root, args) => {
      return new Parent(/* params */);
    },
    // there is a field `child` in the type Query
    child: (root, args) => {
      return new Child(/* params */);
    },
    // there is a field `toy` in the type Query
    toy: (root, args) => {
      return new Toy(/* params */);
    },
  },

  // Parent is defined in the top type level
  Parent: {
    /* optional for scalar type */
    name: (root, args) => root.name,

    /* the children field is used for query for the list of child, and it's recommend to declare it */
    children: (root, args) => {
      /* do something with the nested args */
      return [new Child(), new Child()];
    },
  },

  // Child is defined in the top type level
  Child: {
    toys: (parent, args) => {
      /* do something with the nested args */
      return [new Toy(), new Toy()];
    },
  },

  // Toy is defined in the top type level
  Toy: {
    createdAt: (parent, args) => {
      /* do something with the nested args */
      return new Date();
    },
  },
};

Builtin directives

Custom directives

const { ApolloServer, gql, SchemaDirectiveVisitor } = require('apollo-server');
const { defaultFieldResolver } = require('graphql');

// Create (or import) a custom schema directive
class UpperCaseDirective extends SchemaDirectiveVisitor {
  visitFieldDefinition(field) {
    const { resolve = defaultFieldResolver } = field;
    field.resolve = async function (...args) {
      const result = await resolve.apply(this, args);
      if (typeof result === 'string') {
        return result.toUpperCase();
      }
      return result;
    };
  }
}

// Construct a schema, using GraphQL schema language
const typeDefs = gql`
  directive @upper on FIELD_DEFINITION

  type Query {
    hello: String @upper
  }
`;

// Provide resolver functions for your schema fields
const resolvers = {
  Query: {
    hello: (parent, args, context) => {
      return 'Hello world!';
    },
  },
};

// Add directive to the ApolloServer constructor
const server = new ApolloServer({
  typeDefs,
  resolvers,
  schemaDirectives: {
    upper: UpperCaseDirective,
  },
});

Authorization via Custom Directives

Example Projects

space-explorer: Full-stack apps with Apollo, React in frontend, sqlite, and apollo-server in the backend.

quick-apollo: Use @apollo/client with React, focusing on frontend usage.

Useful Links