Skip to content

ryanhs/sails-graphql-glue

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

71 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Sails Graphql Glue

npm version Coverage Status node npm bundle size

this package is intended to make a glue for express-graphql and sails framework.

Installation

to install is just straight forward:

  • with npm: npm i sails-graphql-glue
  • with yarn: yarn add sails-graphql-glue

Example Graphql Action

ON api/controllers/graphql.js:

/* api/controllers/graphql.js */

var Promise = require('bluebird');
const { actionAsResolver, serve } = require('sails-graphql-glue');

const typeDefs = `
  type Query {
    hello: String!
    helloName(name: String): String!
  }

  schema {
    query: Query
  }
`

const resolvers = {
  Query: {
    hello: async () => Promise.resolve('hello world!'),
    helloName: actionAsResolver(require('./api/hello')),
  }
}

module.exports = serve({typeDefs, resolvers, debug: sails.config.environment === 'development'});

ON config/routes.js add the graphql route:

module.exports.routes = {
  ...

  '/graphql': { action: 'graphql' }
};

Func: actionAsResolver()

This function is to wrap sails action2 into a resolver. so you can use your current action freely. Example: actionAsResolver(require('./api/hello'))

Func: serve()

this function is to glue express-graphql into sails compatible.

+ parameters
  • typeDefs graphql schema
  • resolvers root resolvers
  • debug just to make sure json pretty print, GraphiQL, and full error reporting

Resolver (parent, context, info)

A Resolver in graphql have this common format: (parent, args, context, info) => ...

Therefore, to make it compatible with machine inputs, the parameters changed into $parent, $context, $info.

Parameters from arg extracted into normal machine inputs.

// automatically added into action/machine inputs
{
  "$parent": {
    description: "parent",
    type: 'ref',
    defaultsTo: {},
  },
  "$context": {
    description: "context",
    type: 'ref',
    defaultsTo: {},
  },
  "$info": {
    description: "info",
    type: 'ref',
    defaultsTo: {},
  },
}

you can use context (req), as example:

fn: async ({ $context, name = "test" }) => {
  console.log(Object.keys($context));
  return name
}

// console:
// [
//   ...
//   'headers',
//   ...
//   'url',
//   ...
//   'query',
//   ...
//   'cookies',
//   ...
//   'session',
//   'file',
//   'body',
//   '_body',
//   ...
// ]

this.req

module.exports = {
  friendlyName: 'Me',
  description: 'Get Login Information.',
  inputs: {},
  exits: {},
  fn: async function() {

    console.log(this.req.headers)

    return ({})
  }
};

In those example above, the this.req will be assigned of $context or request object. but in arrow function, it will not. since You cannot "rebind" an arrow function. It will always be called with the context in which it was defined. Just use a normal function.

License

MIT

About

a glue for express-graphql and sails framework

Resources

License

Stars

Watchers

Forks

Packages

No packages published