graphql / express-graphql Goto Github PK
View Code? Open in Web Editor NEWCreate a GraphQL HTTP server with Express.
License: MIT License
Create a GraphQL HTTP server with Express.
License: MIT License
Unable to require the module using import
in Typescript after this change: #92 . It compiles, but seems like the module doesn't have any default export.
Code:
import graphqlHTTP from 'express-graphql';
import schema from './schema';
const graphqlMiddleware:any = graphqlHTTP({
graphiql: true,
pretty: true,
schema: schema,
});
runtime error:
const graphqlMiddleware = express_graphql_1.default({
^
TypeError: express_graphql_1.default is not a function
tsconfig:
"compilerOptions": {
"target": "es2015",
"module": "commonjs",
"moduleResolution": "node"
}
When sending a Content-Type : application/graphql with a query string the request fails.
If using body parser json or url encoded it says that i don't have a query string.
if used with text type application/graphql it gets stuck on parseBody.js in the line 119.
I have a fully stateless backend (token only). Using graphIQL doesn't work because I have no way to pass in my token.
Is there a way to intercept my incoming graphiQL tokens so I can add the token?
I'm using Flow in my project & I'd like to use all the flow definitions from express-graphql, yet they are removed during the build script.
Disclaimer: I'm unfamiliar with how Travis CI works.
I know I can manually download the project to get access to the 'src' directory where the definitions are, but that seems a bit weird. I'd like to use npm install to maintain all my packages + preserve the flow type definitions.
What is the best practice for preserving flow definitions using npm install? & is there a way to do so that is not package specific & would apply to all flow typed libraries?
Let's say you have a <form>
which posts data to API server. The API server validates the input and returns JSON object. If the input is invalid (e.g. invalid email or email already exists in database) an error objects {errors: {email: "already exists"}} is returned.
How do we handle and serve these kind of errors when using GraphQL? How and where should data validation be implemented (should that be part of my GraphQL code, maybe inside each resolve function)?
Hi there, fantastic project. One feature that would be great is the ability to put custom logos or at least some custom text into the logo space.
Cheers.
In Relay you have to pass a complex "input" type into the query. I'm not sure how to use the variables parameter to accomplish this.
It looks like React.render was removed.
Can you provide an example how to use this middleware with multer?
I do not understand how to correctly handle file uploads.
I found a function which is making decision about GraphiQL:
/**
* Helper function to determine if GraphiQL can be displayed.
*/
function canDisplayGraphiQL(request: Request, data: Object): boolean {
// If `raw` exists, GraphiQL mode is not enabled.
var raw = request.query.raw !== undefined || data.raw !== undefined;
// Allowed to show GraphiQL if not requested as raw and this request
// prefers HTML over JSON.
return !raw && request.accepts([ 'json', 'html' ]) === 'html';
}
Requests that Relay send aren't "raw". BTW what is "raw"?
Firefox prefers HTML.
Would https support be possible with this repo or would that be set up with Express before the main constructor from this project gets passed to express.use
?
What is the roadmap/future plans for this repository? I'm working on a GraphQL HTTP server and I'm evaluating whether I should use this project or build my own. I am a little confused on whether this repository is supposed to be a reference implementation for GraphQL HTTP server authors or is this supposed to be the resource for building production grade HTTP GraphQL servers with GraphQL JS. If it is not the latter I ask if that might be reconsidered.
There are a few features which I would like to see before using this in production (in order of importance):
express
dependency. This module could easily be just a connect-style middleware which could then work with express
, connect
, router
, and koa
(off the top of my head). This might warrant a module name change to graphql-http
or something.These are things I would be willing to contribute (as I would be building them on my own anyway…). If I get approval from the current core team I can start developing these things. I would rather contribute to this repository over creating a new one or keeping the code close sourced.
how can i add custom headers to the response, for example to enable cors ?
Are the GraphQL variables passed in through a query exposed in any way? I'd like to pass in a token of some sort and it would be easy through a variable. If not, I could use a header.
Would be nice if the error stack in responses could contain more detailed information.
I incorrectly imported some functions for my schema and undefined is not a function
without any line numbers was very painful to track down the source of the problem.
Warning: Server request for query `AppHomeRoute` failed for the following reasons:
1. undefined is not a function
query AppHomeRoute{game{id,..._0c28183ce}} fragment _1452748
^^^
I'm sure that more experience using express-graphql would make this error's location far easier to find based on the flagging of game{
. I had difficulty finding the actual function that was undefined as I only knew to look somewhere within the game query type.
I noticed the middleware returns JSON with text/json
mime-type. Any reason why it doesn't return application/json
?
I know there is a debate about that for a long time in the community but I thought application/json
became the norm.
Set fetcher to use withCredentials
to allow cookies to be sent for auth.
I get
{
"errors": [
{
"message": "_graphql.Source is not a function"
}
]
}
response when running a query (as described in the readme). If I do console.log(_graphql.Source)
it says undefined
. The graphql(schema)
command works so my schema is ok. Bug?
I was working this graphql and express and reach the moment than I can not hold all fields definitions in schema.js, so I tried to create the folder structure for this case. Which you can reach by link.
I would be glad to discuss this question. Thank you.
Hi !
I have a compressed query in req, and I want to decompress it before send to GraphiQL. Why this code doesn't work ? Is it possible ?
router.use("/debug", (req, res, next) => {
const decompressed = lz.decompressFromEncodedURIComponent(req.query.query);
req.query = {
query : decompressed,
};
next();
}, require("express-graphql")({
schema : graphqlRootSchema,
graphiql : config.get("NODE_ENV") !== "production",
pretty : true,
formatError : format.fromGraphiql
}));
Thx !
I'm running GraphQL on a few virtual machines within Amazon's EC2 service. These virtual machines are accessed via a load balancer. The load balancer performs some health checks to ensure that the virtual machines are healthy. One of the possible health checks is an HTTP "ping" which simply makes a GET request to a specified path and for the response to be considered healthy it has to respond with a 200 code and either a content length header set, or a transfer encoding header set to chunked.
Right now, GraphQL sets neither. I'd imagine the content length would be the one that makes sense for express-graphql, since it doesn't look like it uses chunking(?).
Do you think we could set the content length header in the response? Or do is there a way to add a middleware after graphql's that calculates that and sets the header?
I'm guessing that I'm doing something dumb here, but I can't see it :( Would appreciate some pointers!
Requesting via the JSON protocol works great:
> curl -H "Content-Type:application/json" -XPOST -d '{"query": "{ currentUser { id } }"}' http://localhost:3000/graphql
{
"data": {
"currentUser": {
"id": "f9342aa2-7674-4050-9e6c-559f14c46b52"
}
}
}
But when I attempt to use the application/graphql
protocol, I get:
> curl -H "Content-Type:application/graphql" -XPOST -d "{ currentUser { id } }" http://localhost:3000/graphql
{
"errors": [
{
"message": "Must provide query string."
}
]
}
Performing mutations on an http GET request is typically bad behavior. It's usually only presumed safe to do this if providing some single-use token to avoid CSRF attacks.
express-graphql should not execute mutations on GET requests unless some opt-in is provided.
By default Relay does not send any cookie and so express-graphql middleware won't work with session. We need to explicitly configure the default network layer with this piece of code in the app entry point before calling ReactDOM.render
:
Relay.injectNetworkLayer(
new Relay.DefaultNetworkLayer('http://localhost:3000/graphql', {
credentials: 'same-origin',
})
);
It would be great to document this somewhere because for the moment it seems that session can work out of the box with GraphQL.
Hi,
To enable stack traces, the documentation recommends to provide an error => error
function to the formatError
option. However, like most GraphQLError
properties, stack
is not enumerable and therefore not visible when converting the error object to a JSON string .
So currently the only way to get useful info is to implement a custom format function like this one.
Wouldn't it be simpler to make the error details enumerable (stack, nodes, locations, etc.) in GraphQLError
? If that's not possible, why not providing a common debug function in this package?
I'm requesting to update GraphiQL because In 0.4.5 GraphQLEnum docs use right description for values
// GraphQL HTTP only supports GET and POST methods.
if (request.method !== 'GET' && request.method !== 'POST') {
response.set('Allow', 'GET, POST');
return sendError(
response,
httpError(405, 'GraphQL only supports GET and POST requests.'),
pretty
);
}
Currently if the Express app enables CORS express-graphql
will fail due to the above check sending a 405
error when the OPTIONS
request comes in.
Two options I see:
express-graphql
and enable OPTION
support when true
OPTION
requests by defaultI'd be happy to implement either, or another option, pending approval!
Trying to test the new graphql beta release, but doesn't look like express-graphql supports the breaking changes. I've debugged as far as identifying that https://github.com/graphql/express-graphql/blob/master/src/index.js#L183 isn't taking into account the new context argument, is that everything that would be needed?
After upgrading to latest React NPM packages, rootValue
it's no longer being passed:
The symbol exported when using commonjs style require has changed.
In 0.5.1:
> require('express-graphql')
[Function: graphqlHTTP]
In 0.5.2:
> require('express-graphql')
{ default: [Function: graphqlHTTP] }
Something related to how es modules are transpiled to commonjs I guess.
In graphql,all request is POST and in the same url.
Because of this,the server side can not distinguish which request is slow.
In below query,is there any way to get the TestQuery
value before graphql execute so I can trace the query name and log it's cost time?
Query TestQuery{
ping
}
I am not sure if this is a bug.
At the GraphQL
new GraphQLObjectType({
name: 'MyType',
fields: {
myField: {
type: GraphQLString,
resolve(parentValue, _, { rootValue: { session } }) {
// use session
here
}
}
}
});
I am able to see the session the ID and variables value that I set.
But when I press F5(Refresh), the session ID got refreshed, and the variables values become undefined.
My understanding for server session is, the session will keep alive as long as it is not yet expired. Also, it will be staying as long as we didn't Close the browser.
The case that I am seeing now, is even if I click a link or refresh, the sessionID is already renewed to a new ID, and the value that I previously set for the session variable become undefiend.
Is my understanding on the server session is wrong? or there is a bug on this?
Thanks.
Let's assume I have the type below
const myType = new GraphQLObject({
name: "MyType",
fields: {
foo: {
type: GraphQLBoolean,
resolve: (_) => serviceCall()
},
bar: {
type: GraphQLString,
resolve: (obj) => obj.foo ? "bar1" : "bar2"
}
}
})
foo
is a boolean field and serviceCall
return a promise. I want to be able to compute bar
based on the value of foo
. My problem is that obj.foo
is always undefined
.
I would like to be able to do something like:
resolve: (obj) => {
return obj.foo.then((value) => value ? "bar1" : "bar2")
}
Reading the source I noticed text/json
was used in sendError
instead of application/json
. Is this correct?
I've seen #36 but my need is far more simple. I'd love to have a way to know when a GraphQL query has finished being processed, so that my custom-built logging library can "close the story" of the request (I'm using hierarchical stories). I'm not interested in the result of the request, not even if it was successful or threw an error, just in the fact that it ended.
I see two ways to accomplish this:
The middleware returns its main promise:
expressGraphql = require 'express-graphql'
graphqlMiddleware = expressGraphql (req) ->
schema: gqlServer.getSchema()
rootValue: {story: req.logStory}
expressApp.use '/api/graphql', (req, res) ->
graphqlMiddleware req, res
.finally -> req.logStory.close()
The middleware accepts a callback:
expressApp.use '/api/graphql', expressGraphql (req) ->
schema: gqlServer.getSchema()
rootValue: {story: req.logStory}
done: -> req.logStory.close()
I believe the second alternative is better, since it is simpler and doesn't involve leaking the middleware's implementation details (the fact that it uses promises).
I can propose a PR if you find this idea useful.
I'm currently attempting to get the request body into context
, because part of the body contains a JWT that needs to be decoded. However when I try the following I get undefined
for context
:
app.use('/', graphqlHTTP((req) => ({
schema: Schema,
context: req.body,
pretty: true,
graphiql: false
})));
I logged out req
and I didn't see body
in there. I'm using a react-reach, and adding the following to the body
on the request:
{
query: {...},
queryParams: {...},
options: {
token: '...'
}
}
I know the body
is being interpreted because my queries/mutations that are in the body are being interpreted and executed. Just can't seem to find it when passed to context
.
How can I send custom headers from the GraphiQL client ?
On every client REST APIs it's possible to define headers for the HTTP requests. How can I do the same with this project ?
An API client (GraphiQL) without the possibility to set headers but only the data ? Really ? I can understand GraphiQL is network protocole agnostic when installed as a standalone, but not in the context of this lib ! Indeed express-graphql means http-graphql.
On GraphiQL there is a "Query variables" sections so why not adding a "HTTP headers" section too ?
It's a serious need for many of us.
PS: Please don't tell me to install directly the GraphiQL from this repo graphql/graphiql ... while precisely the purpose of express-graphql is to have an easy and ready to use package preventing to bother with installing each other libs as a standalone.
I installed express-graphql, when I open 112.74.106.164:3000/graphql in the browser, graphiql is loaded. But nothing happen on graphql request. For example:
{
authors {
name
}
}
Mongodb is running well, and this request work if I run directly from the server. But no chance through Graphiql...
Here is my server.js:
require('babel/register');
var express = require('express');
var graphql = require('graphql');
var expressGraphql = require('express-graphql');
var Schema = require('./server/schema.js');
var app = express();
app.use('/', expressGraphql({
schema: Schema,
graphiql: true
}));
app.listen(3000);
console.log('GraphQL Sandbox started on port: 3000');
And here is the schema.js:
const mongo = require('promised-mongo');
const db = mongo('mongodb://localhost/mydb');
const authorsCollection = db.collection('authors');
import * as _ from 'underscore';
import {
GraphQLList,
GraphQLObjectType,
GraphQLSchema,
GraphQLString,
GraphQLInt,
GraphQLFloat,
GraphQLEnumType,
GraphQLNonNull
} from 'graphql';
const Author = new GraphQLObjectType({
name: 'Author',
description: 'Represent the type of an author of a blog post or a comment',
fields: () => ({
_id: {type: GraphQLString},
name: {type: GraphQLString},
twitterHandle: {type: GraphQLString}
})
});
const Query = new GraphQLObjectType({
name: 'RootQuery',
fields: {
authors: {
type: new GraphQLList(Author),
resolve: function() {
return authorsCollection.find().toArray();
}
}
}
});
const Mutation = new GraphQLObjectType({
name: 'Mutations',
fields: {
createAuthor: {
type: Author,
args: {
_id: {type: new GraphQLNonNull(GraphQLString)},
name: {type: new GraphQLNonNull(GraphQLString)},
twitterHandle: {type: GraphQLString}
},
resolve: function(rootValue, args) {
let author = _.clone(args);
return authorsCollection.insert(author)
.then(_ => author);
}
}
}
});
const Schema = new GraphQLSchema({
query: Query,
mutation: Mutation
});
export default Schema;
Any help would be much appreciated, Thanks :)
When I run this query
http://localhost:3001/data?operationName=query&query=%0A%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20count%0A%20%20%20%20%20%20%7D%0A%20%20%20%20
The server returns a 400, {"errors":[{"message":"Must provide an operation."}]}
However without the operation name (as below) it works fine:
http://localhost:3001/data?query=%0A%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20count%0A%20%20%20%20%20%20%7D%0A%20%20%20%20
package.json
{
"name": "stks",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"babel-polyfill": "^6.5.0",
"body-parser": "^1.15.0",
"express": "^4.13.4",
"express-graphql": "^0.4.10",
"graphql": "^0.4.18",
"isomorphic-fetch": "^2.2.1",
"query-string": "^3.0.1",
"react": "^0.14.7",
"react-dom": "^0.14.7",
"react-redux": "^4.4.0",
"react-router": "^2.0.1",
"redux": "^3.3.1",
"redux-thunk": "^2.0.1"
},
"devDependencies": {
"babel-core": "^6.5.2",
"babel-loader": "^6.2.2",
"babel-preset-es2015": "^6.5.0",
"babel-preset-react": "^6.5.0",
"babel-preset-react-hmre": "^1.1.0",
"gulp": "^3.9.1",
"nodemon": "^1.8.1",
"pm2": "^1.0.1",
"raw-loader": "^0.5.1",
"style-loader": "^0.13.0",
"webpack": "^1.12.13",
"webpack-dev-middleware": "^1.5.1",
"webpack-dev-server": "^1.14.1",
"webpack-hot-middleware": "^2.7.1"
},
"scripts": {
"start": "NODE_ENV=dev node index.js",
"build": "webpack && gulp build",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
Thanks
I'm experimenting with the idea of being able to send non-graphql messages back to the client via custom response headers. The idea is to add the response to the rootValue so that resolve functions in mutations can access it. Then i'd do something like rootValue.response.setHeader("X-NotificationMessage", "Jolly Good!")
For this to work, the response needs to be accessible in the advanced function form of graphQLHTTP
How does one build this package if forked. I have forked it and made my changes but I get the following error when trying to import it:
Error: Cannot find module 'express-graphql'
at Function.Module._resolveFilename (module.js:339:15)
at Function.Module._load (module.js:290:25)
at Module.require (module.js:367:17)
at require (internal/module.js:16:19)
at Object.<anonymous> (/Users/jwaldrip/dev/src/github.com/brandfolder/graphqlify/server.js:7:23)
at Module._compile (module.js:413:34)
at loader (/Users/jwaldrip/dev/src/github.com/brandfolder/graphqlify/node_modules/babel-register/lib/node.js:130:5)
at Object.require.extensions.(anonymous function) [as .js] (/Users/jwaldrip/dev/src/github.com/brandfolder/graphqlify/node_modules/babel-register/lib/node.js:140:7)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
I tried also running npm run build
but then got this error:
$ npm run build
> [email protected] build /Users/jwaldrip/dev/src/github.com/brandfolder/express-graphql
> rm -rf dist/* && babel src --ignore __tests__ --out-dir dist
SyntaxError: src/index.js: Unexpected token (19:12)
17 | import { parseBody } from './parseBody';
18 | import { renderGraphiQL } from './renderGraphiQL';
> 19 | import type { Request, Response } from 'express';
| ^
20 |
21 | /**
22 | * Used to configure the graphQLHTTP middleware by providing a schema
npm ERR! Darwin 15.4.0
npm ERR! argv "/usr/local/Cellar/node/5.5.0/bin/node" "/usr/local/bin/npm" "run" "build"
npm ERR! node v5.5.0
npm ERR! npm v3.5.3
npm ERR! code ELIFECYCLE
npm ERR! [email protected] build: `rm -rf dist/* && babel src --ignore __tests__ --out-dir dist`
npm ERR! Exit status 1
How can I access to the response headers since this lib provides only the req
parameter but not res
?
We're running into an issue with GraphiQL that our QA team uncovered where the page won't properly render when the result of the query specified in the query-string "query" parameter includes HTML as a string and it is injected into the page on initial load:
The current workaround is to copy and paste the query into a new page w/o query string or remove the query string and reload, so that the query is loaded from the localStorage.
Hi,
app.use('/graphql', graphqlHTTP(request => ({
schema: MySessionAwareGraphQLSchema,
rootValue: request.session,
graphiql: true
})));
How do I access the rootValue at schema.js?
I can't access session data through graphQLHTTP
My session look like this:
Session {
cookie:
{ path: '/',
_expires: Sat Jan 09 2016 20:51:51 GMT-0800 (PST),
originalMaxAge: 600000,
httpOnly: true
},
viewer: '[email protected]'
}
But if I access like this"
app.use('/graphql', graphQLHTTP(request => ({
schema: querySchema,
rootValue: { session: request.session },
graphiql: true,
pretty: true,
})));
This is what I got:
Session {
cookie:
{ path: '/',
_expires: Sat Jan 09 2016 20:51:51 GMT-0800 (PST),
originalMaxAge: 600000,
httpOnly: true
}
}
}
Hi Lee,
I just finished draft version of GraphiQL that supports HTTP headers.
I know there are multiple discussions about keeping the original GraphiQL version lean and protocol independent, which makes sense to me.
So the question is what's the best way to structure the middle ware here, so we can specify our own custom versions.
At the moment I'm using non flexible solution:
graphQLServer.use('/graphiql', express.static('graphiql'));
But I would want to see something like this possible:
import graphiql from 'graphiql-headers';
app.use('/graphql', graphqlHTTP(request => ({
schema: MySessionAwareGraphQLSchema,
context: request.session,
graphiql: graphiql
})));
What would be accepted as PR?
Thanks for your time on this.
Please upgrade.
I am following the tutorial http://graphql.org/docs/getting-started/,
and when I tried to hit the http://localhost:3000/graphql, I get the error like this:
ReferenceError: Promise is not defined
at /gls16_api/node_modules/express-graphql/dist/index.js:66:9
at Layer.handle as handle_request
at trim_prefix (/gls16_api/node_modules/express/lib/router/index.js:312:13)
at /gls16_api/node_modules/express/lib/router/index.js:280:7
at Function.process_params (/gls16_api/node_modules/express/lib/router/index.js:330:12)
at next (/gls16_api/node_modules/express/lib/router/index.js:271:10)
at expressInit (/gls16_api/node_modules/express/lib/middleware/init.js:33:5)
at Layer.handle as handle_request
at trim_prefix (/gls16_api/node_modules/express/lib/router/index.js:312:13)
at /gls16_api/node_modules/express/lib/router/index.js:280:7
anyone can help?
I recently worked on a mutation, tested it out in graphiql and it checked out. However when attempting to hook it up the a frontend application it fails. I made a SoF post about this, not sure if it is express-graphql. The error at hand is that on this particular mutation for some reason the response payload is "Cannot POST /" along with a 404 code. If you happen to know what may be causing this please comment.
Would be nice if there was some way of post-processing the response. Some use cases:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.