express-graphql
Advanced tools
Comparing version 0.3.0 to 0.4.0
@@ -28,8 +28,16 @@ | ||
var _graphql = require('graphql'); | ||
var _graphqlError = require('graphql/error'); | ||
var _graphqlExecution = require('graphql/execution'); | ||
var _graphqlLanguage = require('graphql/language'); | ||
var _graphqlValidation = require('graphql/validation'); | ||
var _graphqlUtilitiesGetOperationAST = require('graphql/utilities/getOperationAST'); | ||
var _parseBody = require('./parseBody'); | ||
var _renderGraphiQL = require('./renderGraphiQL'); | ||
/** | ||
@@ -53,2 +61,3 @@ * Middleware for express; takes an options object or function as input to | ||
var pretty = _getOptions.pretty; | ||
var graphiql = _getOptions.graphiql; | ||
@@ -62,8 +71,8 @@ // GraphQL HTTP only supports GET and POST methods. | ||
// Parse the Request body. | ||
(0, _parseBody.parseBody)(request, function (error) { | ||
(0, _parseBody.parseBody)(request, function (parseError) { | ||
var data = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
// Format any request errors the same as GraphQL errors. | ||
if (error) { | ||
return sendError(response, error, pretty); | ||
if (parseError) { | ||
return sendError(response, parseError, pretty); | ||
} | ||
@@ -79,5 +88,45 @@ | ||
// If there is no query, present an empty GraphiQL if possible, otherwise | ||
// return a 400 level error. | ||
if (!query) { | ||
if (graphiql && canDisplayGraphiQL(request, data)) { | ||
return response.set('Content-Type', 'text/html').send((0, _renderGraphiQL.renderGraphiQL)()); | ||
} | ||
throw (0, _httpErrors2['default'])(400, 'Must provide query string.'); | ||
} | ||
// Run GraphQL query. | ||
(0, _graphql.graphql)(schema, query, rootValue, variables, operationName).then(function (result) { | ||
new Promise(function (resolve) { | ||
var source = new _graphqlLanguage.Source(query, 'GraphQL request'); | ||
var documentAST = (0, _graphqlLanguage.parse)(source); | ||
var validationErrors = (0, _graphqlValidation.validate)(schema, documentAST); | ||
if (validationErrors.length > 0) { | ||
resolve({ errors: validationErrors }); | ||
} else { | ||
// Only query operations are allowed on GET requests. | ||
if (request.method === 'GET') { | ||
// Determine if this GET request will perform a non-query. | ||
var operationAST = (0, _graphqlUtilitiesGetOperationAST.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 (graphiql && canDisplayGraphiQL(request, data)) { | ||
return response.set('Content-Type', 'text/html').send((0, _renderGraphiQL.renderGraphiQL)({ query: query, variables: variables })); | ||
} | ||
// Otherwise, report a 405 Method Not Allowed error. | ||
response.set('Allow', 'POST'); | ||
return sendError(response, (0, _httpErrors2['default'])(405, 'Can only perform a ' + operationAST.operation + ' operation ' + 'from a POST request.'), pretty); | ||
} | ||
} | ||
// Perform the execution. | ||
resolve((0, _graphqlExecution.execute)(schema, documentAST, rootValue, variables, operationName)); | ||
} | ||
})['catch'](function (error) { | ||
return { errors: [error] }; | ||
}).then(function (result) { | ||
// Format any encountered errors. | ||
@@ -90,3 +139,11 @@ if (result.errors) { | ||
// Otherwise 400:BadRequest if only errors exist. | ||
response.status(result.hasOwnProperty('data') ? 200 : 400).set('Content-Type', 'text/json').send(JSON.stringify(result, null, pretty ? 2 : 0)); | ||
response.status(result.hasOwnProperty('data') ? 200 : 400); | ||
// If allowed to show GraphiQL, present it instead of JSON. | ||
if (graphiql && canDisplayGraphiQL(request, data)) { | ||
response.set('Content-Type', 'text/html').send((0, _renderGraphiQL.renderGraphiQL)({ query: query, variables: variables, result: result })); | ||
} else { | ||
// Otherwise, present JSON directly. | ||
response.set('Content-Type', 'application/json').send(JSON.stringify(result, null, pretty ? 2 : 0)); | ||
} | ||
}); | ||
@@ -121,5 +178,2 @@ }); | ||
var query = request.query.query || data.query; | ||
if (!query) { | ||
throw (0, _httpErrors2['default'])(400, 'Must provide query string.'); | ||
} | ||
@@ -143,2 +197,13 @@ // Parse the variables if needed. | ||
/** | ||
* Helper function to determine if GraphiQL can be displayed. | ||
*/ | ||
function canDisplayGraphiQL(request, data) { | ||
// 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'; | ||
} | ||
/** | ||
* Helper for formatting errors | ||
@@ -148,3 +213,3 @@ */ | ||
var errorResponse = { errors: [(0, _graphqlError.formatError)(error)] }; | ||
response.status(error.status || 500).set('Content-Type', 'text/json').send(JSON.stringify(errorResponse, null, pretty ? 2 : 0)); | ||
response.status(error.status || 500).set('Content-Type', 'application/json').send(JSON.stringify(errorResponse, null, pretty ? 2 : 0)); | ||
} | ||
@@ -163,2 +228,6 @@ module.exports = exports['default']; | ||
* A boolean to configure whether the output should be pretty-printed. | ||
*/ | ||
/** | ||
* A boolean to optionally enable GraphiQL mode | ||
*/ |
@@ -42,4 +42,4 @@ | ||
try { | ||
// If express has already parsed a body, use it. | ||
if (typeof req.body === 'object') { | ||
// If express has already parsed a body as a keyed object, use it. | ||
if (typeof req.body === 'object' && !(req.body instanceof Buffer)) { | ||
return next(null, req.body); | ||
@@ -55,2 +55,13 @@ } | ||
// If express has already parsed a body as a string, and the content-type | ||
// was application/graphql, parse the string body. | ||
if (typeof req.body === 'string' && typeInfo.type === 'application/graphql') { | ||
return next(null, graphqlParser(req.body)); | ||
} | ||
// Already parsed body we didn't recognise? Parse nothing. | ||
if (req.body) { | ||
return next(); | ||
} | ||
// Use the correct body parser based on Content-Type header. | ||
@@ -57,0 +68,0 @@ switch (typeInfo.type) { |
{ | ||
"name": "express-graphql", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"description": "Create a GraphQL HTTP server with Express.", | ||
@@ -54,3 +54,3 @@ "contributors": [ | ||
"peerDependencies": { | ||
"graphql": "~0.4.2" | ||
"graphql": "~0.4.5" | ||
}, | ||
@@ -60,11 +60,13 @@ "devDependencies": { | ||
"babel-core": "5.8.22", | ||
"babel-eslint": "4.0.5", | ||
"babel-eslint": "4.0.10", | ||
"babel-runtime": "5.8.20", | ||
"body-parser": "^1.14.0", | ||
"chai": "3.2.0", | ||
"coveralls": "2.11.4", | ||
"eslint": "1.1.0", | ||
"eslint-plugin-babel": "2.1.1", | ||
"express": "4.13.3", | ||
"express3": "*", | ||
"flow-bin": "0.14.0", | ||
"graphql": "0.4.2", | ||
"graphql": "0.4.5", | ||
"isparta": "3.0.3", | ||
@@ -71,0 +73,0 @@ "mocha": "2.2.5", |
@@ -20,3 +20,3 @@ GraphQL Express Middleware | ||
app.use('/graphql', graphqlHTTP({ schema: MyGraphQLSchema })); | ||
app.use('/graphql', graphqlHTTP({ schema: MyGraphQLSchema, graphiql: true })); | ||
``` | ||
@@ -37,3 +37,6 @@ | ||
* **`graphiql`**: If `true`, may present [GraphiQL][] when loaded directly | ||
from a browser (a useful tool for debugging and exploration). | ||
### HTTP Usage | ||
@@ -51,5 +54,9 @@ | ||
operations, this specifies which operation should be executed. If not | ||
provided, an 400 error will be returned if the `query` contains multiple | ||
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 URL's query-string: | ||
@@ -66,3 +73,3 @@ | ||
for `multipart/form-data` content, which may be useful for GraphQL mutations | ||
involving uploading files. | ||
involving uploading files. See an [example using multer](https://github.com/graphql/express-graphql/blob/master/src/__tests__/http-test.js#L603). | ||
@@ -102,3 +109,4 @@ If the POST body has not yet been parsed, graphql-express will interpret it | ||
schema: MySessionAwareGraphQLSchema, | ||
rootValue: request.session | ||
rootValue: request.session, | ||
graphiql: true | ||
}))); | ||
@@ -108,3 +116,4 @@ ``` | ||
[`graphql-js`]: https://github.com/graphql/graphql-js | ||
[GraphiQL]: https://github.com/graphql/graphiql | ||
[`multer`]: https://github.com/expressjs/multer | ||
[`express-session`]: https://github.com/expressjs/session |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
26037
7
336
114
19
2