feathers-plus / graphql

A high performance GraphQL adapter for SQL and non-SQL databases.

Home Page:https://generator.feathers-plus.com/api/#graphql

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support GraphQL variables

eddyystop opened this issue · comments

Thx @eddyystop for creating a reference to my PR. You are right, after applying the changes to make work passing variables - I have an issue, and I don't have more ideas why this doesn't work, did I miss something?

I found where the problem comes from.
feathers-plus/graphql uses package https://github.com/eddyystop/graphql-resolvers-ast that currently not allow passing argumentValue.kind Variable

function getArgumentValue (argumentValue) {
  switch (argumentValue.kind) {
    case 'StringValue': // fall through
    case 'BooleanValue':
      return argumentValue.value;
    case 'IntValue':
      return parseInt(argumentValue.value, 10);
    case 'FloatValue':
      return parseFloat(argumentValue.value);
    case 'ListValue':
      return argumentValue.values.map(elem => getArgumentValue(elem));
    case 'ObjectValue':
      const obj = {};
      argumentValue.fields.forEach(field => {
        obj[field.name.value] = getArgumentValue(field.value);
      });
      return obj;
    default:
      throw new Error(`Unexpected GraphQL argument type "${argumentValue.kind}"`);
  }
}

I think this is a great feature to allow passing variables with query
Currently i have been implemented my solution to pass query object in variables.
This will helps us to avoid use convertArgsToParams function that replace __ to $

image

Thanks for the info.

Posting here for prosperity, but I do not recommend doing this but make sure you know what you're doing and remember to remove this when it is actually fixed.

  1. add the following to your scripts in package.json: "postinstall": "node src/util/variable-fix.js"
  2. create a new file at the directory: src/util/variable-fix.js
  3. add the following code to the file:
const fs = require('fs');

// eslint-disable-next-line no-console
console.log('Warning!! patching to inject variable support into deps');

const fGQL_dir = `${__dirname}/../../node_modules/@feathers-plus/graphql/lib/index.js`;
const gra_dir = `${__dirname}/../../node_modules/graphql-resolvers-ast/lib/index.js`;

let fGQL = fs.readFileSync(fGQL_dir, {encoding: 'utf8'});
let gra = fs.readFileSync(gra_dir, {encoding: 'utf8'});

fGQL = fGQL.replace('runQuery(query, params) {', 'runQuery(query, params, variables) {');
fGQL = fGQL.replace('graphql(this._schema, query, {}, content)', 'graphql(this._schema, query, {}, content, variables)');
fGQL = fGQL.replace('return this.runQuery(data.query, params);', 'return this.runQuery(data.query, params, data.variables);');
fGQL = fGQL.replace('return this.runQuery(params.query.query, params);', 'return this.runQuery(params.query.query, params, params.query.variables);');

gra = gra.replace('getArgumentValue(argument.value)', 'getArgumentValue(argument.value, ast)');
gra = gra.replace('function getArgumentValue (argumentValue) {', 'function getArgumentValue (argumentValue, ast) {');
gra = gra.replace('elem => getArgumentValue(elem)', 'elem => getArgumentValue(elem, ast)');
gra = gra.replace('getArgumentValue(field.value)', 'getArgumentValue(field.value, ast)');
gra = gra.replace(`
      return obj;
    default:`, `
      return obj;
    case 'Variable':
      return ast.variableValues[argumentValue.name.value];
    default:`);

fs.writeFileSync(fGQL_dir, fGQL);
fs.writeFileSync(gra_dir, gra);

When you run npm install, it will auto patch the node modules to give variable support. If you already have your node_modules installed, you can run npm run postinstall

Once again, not recommended and no warranty is given. This is only for if you needed variables implemented yesterday like me.