Coder Social home page Coder Social logo

koa-graphql's Introduction

GraphQL Koa Middleware

npm version Build Status Coverage Status

Create a GraphQL HTTP server with Koa.

Port from express-graphql.

Installation

npm install --save koa-graphql

TypeScript

This module includes a TypeScript declaration file to enable auto complete in compatible editors and type information for TypeScript projects.

Simple Setup

Mount koa-graphql as a route handler:

const Koa = require('koa');
const mount = require('koa-mount');
const { graphqlHTTP } = require('koa-graphql');

const app = new Koa();

app.use(
  mount(
    '/graphql',
    graphqlHTTP({
      schema: MyGraphQLSchema,
      graphiql: true,
    }),
  ),
);

app.listen(4000);

Setup with Koa Router

With @koa/router:

const Koa = require('koa');
const Router = require('@koa/router');
const { graphqlHTTP } = require('koa-graphql');

const app = new Koa();
const router = new Router();

router.all(
  '/graphql',
  graphqlHTTP({
    schema: MyGraphQLSchema,
    graphiql: true,
  }),
);

app.use(router.routes()).use(router.allowedMethods());

Setup with Koa v1

For Koa 1, use koa-convert to convert the middleware:

const koa = require('koa');
const mount = require('koa-mount'); // [email protected]
const convert = require('koa-convert');
const { graphqlHTTP } = require('koa-graphql');

const app = koa();

app.use(
  mount(
    '/graphql',
    convert.back(
      graphqlHTTP({
        schema: MyGraphQLSchema,
        graphiql: true,
      }),
    ),
  ),
);

Setup with Subscription Support

const Koa = require('koa');
const mount = require('koa-mount');
const { graphqlHTTP } = require('koa-graphql');
const typeDefs = require('./schema');
const resolvers = require('./resolvers');
const { makeExecutableSchema } = require('graphql-tools');
const schema = makeExecutableSchema({
  typeDefs: typeDefs,
  resolvers: resolvers,
});
const { execute, subscribe } = require('graphql');
const { createServer } = require('http');
const { SubscriptionServer } = require('subscriptions-transport-ws');
const PORT = 4000;
const app = new Koa();
app.use(
  mount(
    '/graphql',
    graphqlHTTP({
      schema: schema,
      graphiql: {
        subscriptionEndpoint: `ws://localhost:${PORT}/subscriptions`,
      },
    }),
  ),
);
const ws = createServer(app.callback());
ws.listen(PORT, () => {
  // Set up the WebSocket for handling GraphQL subscriptions.
  new SubscriptionServer(
    {
      execute,
      subscribe,
      schema,
    },
    {
      server: ws,
      path: '/subscriptions',
    },
  );
});

Options

The graphqlHTTP function accepts the following options:

  • schema: A GraphQLSchema instance from graphql-js. A schema must be provided.

  • graphiql: If true, presents GraphiQL when the GraphQL endpoint is loaded in a browser. We recommend that you set graphiql to true when your app is in development, because it's quite useful. You may or may not want it in production. Alternatively, instead of true you can pass in an options object:

    • defaultQuery: An optional GraphQL string to use when no query is provided and no stored query exists from a previous session. If undefined is provided, GraphiQL will use its own default query.

    • headerEditorEnabled: An optional boolean which enables the header editor when true. Defaults to false.

    • subscriptionEndpoint: An optional GraphQL string contains the WebSocket server url for subscription.

    • websocketClient: An optional GraphQL string for websocket client used for subscription, v0: subscriptions-transport-ws, v1: graphql-ws. Defaults to v0 if not provided

    • shouldPersistHeaders

    • editorTheme: By passing an object you may change the theme of GraphiQL. Details are below in the Custom GraphiQL themes section.

  • rootValue: A value to pass as the rootValue to the execute() function from graphql-js/src/execute.js.

  • context: A value to pass as the context to the execute() function from graphql-js/src/execute.js. If context is not provided, the ctx object is passed as the context.

  • pretty: If true, any JSON response will be pretty-printed.

  • extensions: An optional function for adding additional metadata to the GraphQL response as a key-value object. The result will be added to the "extensions" field in the resulting JSON. This is often a useful place to add development time metadata such as the runtime of a query or the amount of resources consumed. This may be an async function. The function is given one object as an argument: { document, variables, operationName, result, context }.

  • validationRules: Optional additional validation rules that queries must satisfy in addition to those defined by the GraphQL spec.

  • customValidateFn: An optional function which will be used to validate instead of default validate from graphql-js.

  • customExecuteFn: An optional function which will be used to execute instead of default execute from graphql-js.

  • customFormatErrorFn: An optional function which will be used to format any errors produced by fulfilling a GraphQL operation. If no function is provided, GraphQL's default spec-compliant formatError function will be used.

  • customParseFn: An optional function which will be used to create a document instead of the default parse from graphql-js.

  • formatError: is deprecated and replaced by customFormatErrorFn. It will be removed in version 1.0.0.

  • fieldResolver

  • typeResolver

In addition to an object defining each option, options can also be provided as a function (or async function) which returns this options object. This function is provided the arguments (request, response, graphQLParams) and is called after the request has been parsed.

The graphQLParams is provided as the object { query, variables, operationName, raw }.

app.use(
  mount(
    '/graphql',
    graphqlHTTP(async (request, response, ctx, graphQLParams) => ({
      schema: MyGraphQLSchema,
      rootValue: await someFunctionToGetRootValue(request),
      graphiql: true,
    })),
  ),
);

HTTP Usage

Once installed at a path, koa-graphql will accept requests with the parameters:

  • query: A string GraphQL document to be executed.

  • variables: The runtime values to use for any GraphQL query variables as a JSON object.

  • operationName: If the provided query contains multiple named operations, this specifies which operation should be executed. If not provided, a 400 error will be returned if the query contains multiple named operations.

  • raw: If the graphiql option is enabled and the raw parameter is provided, raw JSON will always be returned instead of GraphiQL even when loaded from a browser.

GraphQL will first look for each parameter in the query string of a URL:

/graphql?query=query+getUser($id:ID){user(id:$id){name}}&variables={"id":"4"}

If not found in the query string, it will look in the POST request body.

If a previous middleware has already parsed the POST body, the request.body value will be used. Use multer or a similar middleware to add support for multipart/form-data content, which may be useful for GraphQL mutations involving uploading files. See an example using multer.

If the POST body has not yet been parsed, koa-graphql will interpret it depending on the provided Content-Type header.

  • application/json: the POST body will be parsed as a JSON object of parameters.

  • application/x-www-form-urlencoded: the POST body will be parsed as a url-encoded string of key-value pairs.

  • application/graphql: the POST body will be parsed as GraphQL query string, which provides the query parameter.

Combining with Other koa Middleware

By default, the koa request is passed as the GraphQL context. Since most koa middleware operates by adding extra data to the request object, this means you can use most koa middleware just by inserting it before graphqlHTTP is mounted. This covers scenarios such as authenticating the user, handling file uploads, or mounting GraphQL on a dynamic endpoint.

This example uses koa-session to provide GraphQL with the currently logged-in session.

const Koa = require('koa');
const mount = require('koa-mount');
const session = require('koa-session');
const { graphqlHTTP } = require('koa-graphql');

const app = new Koa();
app.keys = ['some secret'];
app.use(session(app));
app.use(function* (next) {
  this.session.id = 'me';
  yield next;
});

app.use(
  mount(
    '/graphql',
    graphqlHTTP({
      schema: MySessionAwareGraphQLSchema,
      graphiql: true,
    }),
  ),
);

Then in your type definitions, you can access the ctx via the third "context" argument in your resolve function:

new GraphQLObjectType({
  name: 'MyType',
  fields: {
    myField: {
      type: GraphQLString,
      resolve(parentValue, args, ctx) {
        // use `ctx.session` here
      },
    },
  },
});

Providing Extensions

The GraphQL response allows for adding additional information in a response to a GraphQL query via a field in the response called "extensions". This is added by providing an extensions function when using graphqlHTTP. The function must return a JSON-serializable Object.

When called, this is provided an argument which you can use to get information about the GraphQL request:

{ document, variables, operationName, result, context }

This example illustrates adding the amount of time consumed by running the provided query, which could perhaps be used by your development tools.

const { graphqlHTTP } = require('koa-graphql');

const app = new Koa();

const extensions = ({
  document,
  variables,
  operationName,
  result,
  context,
}) => {
  return {
    runTime: Date.now() - context.startTime,
  };
};

app.use(
  mount(
    '/graphql',
    graphqlHTTP((request) => {
      return {
        schema: MyGraphQLSchema,
        context: { startTime: Date.now() },
        graphiql: true,
        extensions,
      };
    }),
  ),
);

When querying this endpoint, it would include this information in the result, for example:

{
  "data": { ... },
  "extensions": {
    "runTime": 135
  }
}

Additional Validation Rules

GraphQL's validation phase checks the query to ensure that it can be successfully executed against the schema. The validationRules option allows for additional rules to be run during this phase. Rules are applied to each node in an AST representing the query using the Visitor pattern.

A validation rule is a function which returns a visitor for one or more node Types. Below is an example of a validation preventing the specific field name metadata from being queried. For more examples, see the specifiedRules in the graphql-js package.

import { GraphQLError } from 'graphql';

export function DisallowMetadataQueries(context) {
  return {
    Field(node) {
      const fieldName = node.name.value;

      if (fieldName === 'metadata') {
        context.reportError(
          new GraphQLError(
            `Validation: Requesting the field ${fieldName} is not allowed`,
          ),
        );
      }
    },
  };
}

Disabling Introspection

Disabling introspection does not reflect best practices and does not necessarily make your application any more secure. Nevertheless, disabling introspection is possible by utilizing the NoSchemaIntrospectionCustomRule provided by the graphql-js package.

import { NoSchemaIntrospectionCustomRule } from 'graphql';

app.use(
  mount(
    '/graphql',
    graphqlHTTP((request) => {
      return {
        schema: MyGraphQLSchema,
        validationRules: [NoSchemaIntrospectionCustomRule],
      };
    }),
  ),
);

Custom GraphiQL Themes

To use custom GraphiQL theme you should pass to graphiql option an object with the property editorTheme. It could be a string with the name of a theme from CodeMirror

router.all(
  '/graphql',
  graphqlHTTP({
    schema: MyGraphQLSchema,
    graphiql: {
      editorTheme: 'blackboard',
    },
  }),
);

List of available CodeMirror themes

or an object with url and name properties where url should lead to your custom theme and name would be passed to the GraphiQL react element on creation as the editorTheme property

router.all(
  '/graphql',
  graphqlHTTP({
    schema: MyGraphQLSchema,
    graphiql: {
      editorTheme: {
        name: 'blackboard',
        url: 'https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.53.2/theme/erlang-dark.css',
      },
    },
  }),
);

For details see the GraphiQL spec

Additional Validation Rules

GraphQL's validation phase checks the query to ensure that it can be successfully executed against the schema. The validationRules option allows for additional rules to be run during this phase. Rules are applied to each node in an AST representing the query using the Visitor pattern.

A validation rule is a function which returns a visitor for one or more node Types. Below is an example of a validation preventing the specific field name metadata from being queried. For more examples see the specifiedRules in the graphql-js package.

import { GraphQLError } from 'graphql';

export function DisallowMetadataQueries(context) {
  return {
    Field(node) {
      const fieldName = node.name.value;

      if (fieldName === 'metadata') {
        context.reportError(
          new GraphQLError(
            `Validation: Requesting the field ${fieldName} is not allowed`,
          ),
        );
      }
    },
  };
}

Debugging Tips

During development, it's useful to get more information from errors, such as stack traces. Providing a function to customFormatErrorFn enables this:

customFormatErrorFn: (error, ctx) => ({
  message: error.message,
  locations: error.locations,
  stack: error.stack ? error.stack.split('\n') : [],
  path: error.path,
});

Examples

Other Relevant Projects

Please checkout awesome-graphql.

Contributing

Welcome pull requests!

License

MIT

koa-graphql's People

Contributors

alexsey avatar axetroy avatar chentsulin avatar clarkdo avatar dependabot[bot] avatar dios-david avatar entropitor avatar maxdesiatov avatar neighborhood999 avatar seidelmartin avatar sibelius avatar sonnypgs avatar thewillhuang avatar tornqvist avatar tryshchenko avatar tuckerconnelly avatar yanickrochon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

koa-graphql's Issues

support fieldResolver

Latest graphql already add fieldResolver in execution, koa-graphql should keep up with it.

Session value example

In the express-graphql repo, there is an example in the Readme demonstrating session usage. How will that look like with koa-graphql? Basically, I want to access session variables and use it in my schema

GraphQL v14 support

Right now koa-graphql supports an old version of graphql (0.13.2), but the latest one is v14.0.2. This should be fixed because GraphQL doesn't support to have multiple instances installed.

If you need any help with this update I could try to make a PR for it ๐Ÿ‘

Expose GetBody Limits?

Allow limit to be passed instead of forcing it to 100Kb. Just got an error in production while doing a demo and flipped. At least set the default to something like 1mb or 2mb.

async function in compiled version 0.7.0

in koa-graphql 0.7.0, the compiled version has async syntax

we are using node 6.10.0 LTS (https://github.com/nodejs/LTS)

node_modules/koa-graphql/dist/index.js:38
  return async function middleware(ctx) {
               ^^^^^^^^
SyntaxError: Unexpected token function
    at Object.exports.runInThisContext (vm.js:76:16)
    at Module._compile (module.js:542:28)
    at Module._extensions..js (module.js:579:10)

how to using koa-graphql with [email protected]

i used koa-router and koa-graphql with koa2 like this:

var router = new Router();
router.use('/graphql',graphqlHTTP({schema: schema}));
app.use(router.routes());

when i visite /graphql. but the router not work.
how do i do. thx.

[flow] type error

I am using koa-graphql with flow, and it throw error with can not find module "express".
Because express-graphql import express with flow, we need to install express in the project. However, we use koa, not express, this is strange.

graphiql option seems to ignore false value

I'm trying to disable GraphiQL and it doesn't seem to be working even though that I explicitly pass false value to it:

app.use(convert(graphqlHTTP(async req => {
  return {
    graphiql: false,
    schema,
    context: {
      ...
    },
    ...
  };
})));

Read response object after koa-graphql has run

I'd like to read the response object that's going to be sent back to the requestor. When I interrogate the response object that's passed when providing a function to koa-graphql, it seems it's before the final response has been composed.

i.e.

function middleware() {
 return graphqlHTTP(
    (request: Object, response: Object, params: Object): Object => {
      // read the response that will be provided to the requestor
      // the response at this point in time is incomplete, it seems. In fact, the status code will be 404.
      return {
        schema,
        graphiql: enableGraphiql || isNotProd,
        formatError: errorFormatterWithMetadata,
        pretty: prettifyJsonResponse,
        extensions: extensionWithMetadata,
        validationRules: additionalValidation,
      }
    },
  )
 }
}

Q: Thoughts on debugging tools?

It would be great if we could pass an option that logs the request query and variables and the response data. Does that belong in this library or should I create like koa-graphql-logging?

Execution after validation failed.

Hi,
I'm writing complexity validator.
But I found that still processing query after return 400.
And the point is in koa-graphgl/dist/index.js line 132 ~ 138

        // Validate AST, reporting any errors.
        var validationErrors = (0, _graphql.validate)(schema, documentAST, validationRules);
        if (validationErrors.length > 0) {
          // Return 400: Bad Request if any validation errors exist.
          response.status = 400;
          resolve({ errors: validationErrors });
        }

And it can simple change by add return after calling resolve.

In express-graphql implementation it will not continue execution after validation failed.

Maybe we can add a option to determine whether it should be execute after validation failed or not.
It would be great.

How to yield in a resolver?

I'm trying to use the generator in the resolver of a graphql type? But it doesn't seem to work.

new GraphQLObjectType({
  name: 'MyType',
  fields: {
    myField: {
      type: GraphQLString,
      resolve: function *(parentValue, args, session) {
          return yield fetch("/some/api")
      }
    }
  }
});

The returned value is this

{
  "myField": ["Object generator"]
}

I guess its not possible to make resolvers synchronous using yields.

Impossible to access cookies within mutateAndGetPayload

Hello here

At first glance this library looks nice, unless you start working with it and end up stack with poor documentation. I have a very simple and very common use case. I want to handle auth. through session and by having LoginMutation I need to access ctx inside it so I can:

  1. set cookies
  2. access ctx.* objects

Without such information - it's completely useless.

Right now I've tried to set cookies on 2nd and 3rd argument. Nothing works.
Attempted to pass values through rootValue - same.
It's literally impossible to use that library when everything in Koa is running around ctx

It's either me not understanding something or my case is super rare

server.js

router.all(
  '/graphql',
  graphqlHTTP((request, ctx) => ({
    schema: graphqlSchema,
    graphiql: true,
    rootValue: { ctx },
    pretty: true,
  })),
)

LoginMutation.js

  mutateAndGetPayload: async ({ email, password }, ctx) => {
    ctx.cookies.set('mykEY', '123')
    console.log(`ctx.cookies.set: ${ctx.cookies.get('mykEY')}`) //nothing
}

When I do that inside middleware - it works!

server.js

app.user(mymw)

mymw.js

export default async function sessionMiddleware(ctx, next) {
  console.log(`ctx.cookies.set: ${ctx.cookies.get('mykEY')}`)
  ctx.cookies.set('mykEY', '123') // here

//2nd call and it's there

install from github

is it possible to install koa-graphql directly from github?

npm i git+ssh://[email protected]/chentsulin/koa-graphql.git --save

the folder of koa-graphql it is empty inside node_modules when I install from github

The types of 'astNode.loc' are incompatible between these types

I'm trying make simple server with the following code :
`
import { buildSchema } from 'graphql';

const graphqlRouter = new Router();
graphqlRouter.all(
/gql,
graphqlHTTP({
schema: buildSchema(
type Query { hello: String }
),
graphiql: false,
}),
);
`

but on line schema shows this:

Type 'import("node_modules/graphql/type/schema").GraphQLSchema' is not assignable to type 'import("node_modules/@types/koa-graphql/node_modules/graphql/type/schema").GraphQLSchema'.
The types of 'astNode.loc' are incompatible between these types.
Property 'toJSON' is missing in type 'import("node_modules/graphql/language/ast").Location' but required in type 'import("node_modules/@types/koa-graphql/node_modules/graphql/language/ast").Location'.ts(2322)

my setup includes

  • "type-graphql": "^1.0.0-rc.2",
  • "koa-graphql": "^0.8.0" & @types/koa-graphql": "^0.8.4"

Perform mutation on GET

Hello, thanks for this awesome lib.
Are there any special reasons for not allowing mutations on GET?

koa-graphql/src/index.js

Lines 229 to 249 in 4d6d9c3

// Only query operations are allowed on GET requests.
if (request.method === 'GET') {
// Determine if this GET request will perform a non-query.
const operationAST = getOperationAST(documentAST, operationName);
if (operationAST && operationAST.operation !== 'query') {
// If GraphiQL can be shown, do not perform this query, but
// provide it to GraphiQL so that the requester may perform it
// themselves if desired.
if (showGraphiQL) {
return resolve(null);
}
// Otherwise, report a 405: Method Not Allowed error.
response.set('Allow', 'POST');
throw httpError(
405,
`Can only perform a ${operationAST.operation} operation ` +
'from a POST request.',
);
}
}

Fix coverage reporting

The README badges still point to the previous repository location, while updating it, the Coverall badge is no longer valid (at least it isn't updated with latest reports).

Furthermore, coverage is actually disabled in .travis.yml so the coverage report has not been updated in a while anyway.

Exposing graphql request?

I know that you can access the request object when you initiate the middleware but is it possible for me to get the graphql request's info also so that I can log it,
example:

graphqlHTTP((request, context) => {
       console.log(request.graphqlQuery);
       console.log(request.graphqlVariables);
})

Right now when I make a post request, I don't know what requests are hitting my server?

Working with query in resolve()

I am stuck with how to work with the incoming query. I want to be able to pass the requested fields from the graphql query and pass them to my controller which ultimately down the line sends those to my mySQL find() function which does a select id, name from Company.

I need to be able to send id, name (or whatever the fields from the graph is that is requested) which I get from the graphql query that's incoming so that my find() can dynamically return requested fields per the graphql query.

I wrote this test:

it.only('returns company data', async () => {
    const stub = {
        data: {
          Company: {
            id: 1,
            name: 'Pivotal'
          }
        }
      },
      query = queryString({
        query: `{
          company { 
            id,
            name
          }
        }`
      }),
      url = `/graphql?${query}`,
      response = await request
        .get(url),
      reponseData = JSON.parse(response.text);

    expect(reponseData).to.deep.equal(stub);
  });

and it's using one of your helpers I found in your tests (I renamed it to queryString):

function queryString(urlParams?: ?{ [param: string]: mixed }) {
  let querystring
  if (urlParams) {
    querystring = stringify(urlParams);
  }
  return querystring;
}

When I run this test, I see the following being passed to superagent:

screen shot 2017-09-09 at 12 42 06 pm

On the koa service side, using koa-graphql, I have it setup like this:

import {
  graphql,
  GraphQLSchema,
  GraphQLObjectType,
  GraphQLID,
  GraphQLString
} from 'graphql';

import Companies from '../controllers/Company';

const Company = new GraphQLObjectType({
    name: 'Company',
    fields: () => ({
      id: {
        type: GraphQLID
      },
      name: {
        type: GraphQLString
      }
    })
  }),

  Query = new GraphQLObjectType({
    name: 'Query',
    fields: () => ({
      company: {
        type: Company,
        resolve(parentValue, args, ctx) {
          //not quite sure what to do here.  I need filter to represent an array of requested fields (in this case it's id and name)  from the graphql query or something like that
          const company = async () => Companies.find(filter);
          return company;
        }
      }
    })
  }),

/*  resolve() {
  return {
    id: 1,
    name: 'Pivotal'
  };
}*/

  mySqlSchema = new GraphQLSchema({
    query: Query
  });

export default mySqlSchema;

or am I going about this the wrong way?

Merge `data` and `errors` into response body instead of re-assign

Hello. This module works pretty well. I am suggesting an enhancement. After executing and resolving GraphQL, the results are assigned to the response.body https://github.com/chentsulin/koa-graphql/blob/master/src/index.js#L294-L296.

This will overwrite any other information that the server might have set. There may be additional information we want to send down that isn't part of the schema. Perhaps instead of a reassignment, it could attempt an object merge so that the developer can send down other information. I've put in PR #103 for this suggestion.

The graphiql property doesn't allow assigning any value with type other than a boolean (TypeScript).

  • Typescript: 3.9.3
  • koa-graphql: 0.8.0
  • @types/koa-graphql: 0.8.3

I'm tried to set up the "Darkula" theme for GraphiQL following this manual: Custom GraphiQL themes, but get an error about a type.

Type '{ editorTheme: string; }' is not assignable to type 'boolean'.

Code

graphqlHTTP({
    schema,
    graphiql: {
        editorTheme: 'darkula',
    },
})

Type definitions

    /**
     * A boolean to optionally enable GraphiQL mode.
     */
    graphiql?: boolean;

Koa 2.x

Will need to support async await with koa 2.0:

app.use(async (ctx, next) => {
  // ...
  await next();
  // ...
});

Support HEAD method for /graphql

I have multiple instances of GraphQL servers running behind a AWS ELB (elastic load balancer).

ELB recurrently checks the status of each node performing a small ping to each node. AWS default validation mode uses HEAD method (it will not use GET or POST).

Currently (as far I was able to check) koa-graphql will return a error if a HEAD request is performed. This causes ELB to assume that the node is dead and will stop to route requests.

Need HEAD to also be supported

Flow error

I get the next flow error using this library:

node_modules/koa-graphql/dist/index.js.flow:164
164:       req.body = req.body || request.body;
               ^^^^ property `body`. Property not found in
164:       req.body = req.body || request.body;
           ^^^ http$IncomingMessage

Status of this Module?

Hi, what is the status of this module, there are some upgrades due by now I think and as active user I'm a bit concerned.
BG

"regeneratorRuntime is not defined"

with 5.3, I now get this:

general error:  ReferenceError: regeneratorRuntime is not defined
    at graphqlHTTP (/Users/dev/app/node_modules/koa-graphql/dist/index.js:41:10)

Input Data of a Mutation are not based on Standard JavaScript Object/ Array

If I have a mutation like this:

import { mutationWithClientMutationId } from 'graphql-relay';
export default mutationWithClientMutationId({
  name: 'BulkImportOrganizations',
  inputFields: {
    listOfOrganizations: {
      type: new GraphQLList(OrganizationType),
    },
    apiKey: {
      type: GraphQLString,
    },
  },
  mutateAndGetPayload: async({ listOfOrganizations, apiKey }) => {
    const output = {
      regStatus: [],
      error: {
        code: [],
        message: []
      }
    };

I wounder why is listOfOrganizations not an array? It seems to be a pseudo array but does not implement the corresponding methods according to the Array Prototype neither it has the Array prototype. The same goes for plain Objects.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.