Giter VIP home page Giter VIP logo

graphql-http's People

Contributors

acao avatar d-exclaimation avatar enisdenjo avatar github-actions[bot] avatar glasser avatar semantic-release-bot avatar spawnia avatar trevor-scheer avatar xilesun 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

graphql-http's Issues

Error: The GraphQL schema is not provided (Express)

Screenshot

Expected Behaviour

I followed the recipe from https://github.com/graphql/graphql-http#recipes for migration from express-graphql. When I run the server I would expect it to work as with express-graphql (no errors).

Actual Behaviour

When starting the server I get:

0|www    | Internal error occurred during request handling. Please check your implementation. Error: The GraphQL schema is not provided
0|www    |     at handler (/Users/e/Desktop/projects/my/node_modules/graphql-http/lib/handler.js:202:23)
0|www    |     at processTicksAndRejections (node:internal/process/task_queues:96:5)
0|www    |     at async requestListener (/Users/e/Desktop/projects/my/node_modules/graphql-http/lib/use/express.js:28:34)

Debug Information
Help us debug the bug?

Further Information

Using:

  • graphql-http 1.7.0
  • @graphql-tools/schema 9.0.4 to create my schema (is this not supported?)

Add extensions function to createHandler

Story

As a server, I want to add an extensions callback function similar to what's available in the express-graphql package options
so that I can add additional key-value metadata to each response. This is useful for capturing runtime and metrics for a given request.

Acceptance criteria

  • The graphql-http createHandler function should have an optional extensions 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 }.

Export parseRequestParams similar to express-graphql

Story

As a _user

I want parseRequestParams function to be exported

So that same implementation can be used outside the package when interacting with graphql-http.
This was the behaviour in express-graphql implementation.

Acceptance criteria

  • _user I can access parseRequestParams from graphql-http package.

Allow to configure the rootValue

Story

As a user migrating from express-graphql, I want to pass a rootValue resolver. With express-graphql, I was able to do the following:

app.get('/graphql', graphqlHTTP((req, res) => ({
  schema,
  rootValue: resolvers
})))

Ideally, I would like to set rootValue as an option of createHandler

app.use(
  '/graphql',
  createHandler({ schema,  rootValue }),
)

Acceptance criteria

  • user is able to configure a rootValue without overriding the whole ExecutionContext with onSubscribe
  • user can find documentation on how to configure a rootValue

Note

Maybe using a rootValue is not recommended anymore? Maybe there's an alternative? For reference, here's how I declare my schema/resolvers:

module.exports = {
  /**
   * Create an article.
   */
  articles: async (args, { req }) => {
    // ...
  }
  /**
   * Delete an article.
   */
  deleteArticle: async (args, { req }) => {
    // ...
  },
}
const gql = require('graphql-tag')
const { buildASTSchema } = require('graphql')

module.exports = buildASTSchema(gql`
  type Article {
    _id: ID!
    title: String
    content: String
    createdAt: String
    updatedAt: String
  }

  type RootQuery {
    articles (user: ID): [Article!]!
  }

  type RootMutation {
    deleteArticle(article: ID!): Article!
  }

  schema {
    query: RootQuery
    mutation: RootMutation
  }
`)

`SHOULD not contain the data entry on JSON parsing failure when accepting application/graphql-response+json` also fails on non-JSON responses

The audit SHOULD not contain the data entry on JSON parsing failure when accepting application/graphql-response+json does this:

        assert(
          'Data entry',
          (await assertBodyAsExecutionResult(res)).data,
        ).toBe(undefined);

This will throw if the body is not actually JSON, with the misleading error about "SHOULD not contain the data entry".

First, I'm not actually sure if the spec actually has a SHOULD that JSON parse errors should be returned as JSON at all (as opposed to having opinions about its structure if it is JSON). Apollo Server now expects you to use your web framework's JSON parsing capabilities (eg, body-parser with Express) rather than handling it "in-house" and it is primarily structured as a non-error-handling middleware, so it's challenging for us to respond to invalid JSON with any particular error format. Maybe that's a self-imposed limitation but we're probably not going to change it. But I don't really see anything that says you SHOULD have a JSON response here. There's

When a server receives a well-formed GraphQL-over-HTTP request, it must return a well‐formed GraphQL response.

but in this case there is no well-formed request, so that doesn't apply.

Second, even if this is a legitimate thing to (optionally) test for, I think it should probably be explicitly tested for separately from this test case, and this particular test shouldn't fail claiming there's a data entry where there really isn't one. ie if the response is not JSON at all then I think this test should pass?

Add graphiql in createHandler method

Story

As a user or client or server

I want some feature

So that some value

Acceptance criteria

  • user or client or server type is able to...
  • user or client or server type can add...
  • user or client or server type can remove...

Audits shouldn't require you to know the URL in order to generate the list of tests

I would like to integrate the audits in my Jest test suite as shown in the README.

I don’t want to have a fixed port for my URL: I want to be able to listen on port 0 and get the URL back and pass that to the tests.

But I don’t want to actually start and listen on a server at the “top level” of a file, because I don't want it to run unless the particular tests are selected (eg, if it.only or the like disables this part of the test file, I don't want to start a server). So listening should go in beforeAll or beforeEach or something.

But you need to give Jest the list of tests before this code runs, and the API here only gives you the list of audit tests once you already have an URL.

It would work better if the url was an argument to fn instead, or if you can pass a function returning an URL or something.

`graphql` seems to have an issue with vite-node

I apologize if this bug is invalid. I tried searching the internet for similar issues but could not find one.

I believe this has something to do with how libraries are bundled in vite-node.

Here is a reproduction

https://stackblitz.com/edit/stackblitz-starters-se6shc

node src/server.js works but running yarn dev fails

If this is a vite-node or graphql issue, let me know.

Many things can be wrong or it all may just be an incompatibility issue. It would be nice if someone could explain what is going on and let others know the solution if they are encountering the same issue.

Add Graphiql

express-graphql had a Graphiql. And that module is now deprecated. I want that feature in this module.

Should have audits for accepting `null`s

The spec has a paragraph that states:

Note: Specifying null in JSON (or equivalent values in other formats) as values for optional request parameters is equivalent to not specifying them at all.

The audit suite should test this explicitly.

(I was inspired by the audit suite to be stricter about banning things like variables: 0 and got carried away and also banned variables: null. So the suite should prevent this over-fitting.)

Server compliance audit through a website

Create an online website which accepts an URL and performs a GQL over HTTP audit for quick checks without having to install anything.

Would work for local servers too because you can simply provide a localhost address too.

Compatibility with graphql-upload

Hi,

First, thanks for all the work you are doing for these libraries!

Its not much of an issue as it is a question following my transition from express-graphql to graphql-http. Express-graphql used to work with graphql-upload but now it seems to me that the handler is blocking my POST request with an image because the Content-Type is not "application/json".

Is this limitation is expected?

Thanks,

Expected Behaviour
I expect this library to accept multipart/form-data Content-Type.

Actual Behaviour
Right now, the library only accepts "application/json" as Content-Type for POST requests. Otherwise, it throws a 415 Unsupported Media Type

Branching audits

For example, a server MAY support GET requests - if it does, it MUST do this and that.

Additionally something like "watershed readiness" checks; for example, express-graphql should pass the basic tests but won't pass the watershed test because how could it (it's depricated)?

`Module '"graphql-http"' has no exported member '...'` happens with ESM TypeScript

Screenshot
Screenshot 2023-03-31 at 15 12 15

% yarn run -s ts-node-esm test.ts
warning package.json: No license field
/private/tmp/a/node_modules/ts-node/src/index.ts:859
    return new TSError(diagnosticText, diagnosticCodes, diagnostics);
           ^
TSError: ⨯ Unable to compile TypeScript:
test.ts:1:10 - error TS2305: Module '"graphql-http"' has no exported member 'createHandler'.

1 import { createHandler } from 'graphql-http';
           ~~~~~~~~~~~~~

    at createTSError (/private/tmp/a/node_modules/ts-node/src/index.ts:859:12)
    at reportTSError (/private/tmp/a/node_modules/ts-node/src/index.ts:863:19)
    at getOutput (/private/tmp/a/node_modules/ts-node/src/index.ts:1077:36)
    at Object.compile (/private/tmp/a/node_modules/ts-node/src/index.ts:1433:41)
    at transformSource (/private/tmp/a/node_modules/ts-node/src/esm.ts:400:37)
    at /private/tmp/a/node_modules/ts-node/src/esm.ts:278:53
    at async addShortCircuitFlag (/private/tmp/a/node_modules/ts-node/src/esm.ts:409:15)
    at async nextLoad (node:internal/modules/esm/loader:163:22)
    at async ESMLoader.load (node:internal/modules/esm/loader:605:20)
    at async ESMLoader.moduleProvider (node:internal/modules/esm/loader:457:11) {
  diagnosticCodes: [ 2305 ]
}

Expected Behaviour
I expected it to work importing graphql-http module with ESM TypeScript.

Actual Behaviour
but instead it did fail with Module '"graphql-http"' has no exported member '...' error.

Debug Information
test.ts

import { createHandler } from 'graphql-http';

package.json

{
  "type": "module",
  "dependencies": {
    "graphql": "^16.6.0",
    "graphql-http": "^1.17.0"
  },
  "devDependencies": {
    "ts-node": "^10.9.1",
    "typescript": "^5.0.3"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "module": "esnext",
    "moduleResolution": "nodenext",
    "strict": true
  }
}

Further Information

Looking at the type definition of graphql-http in node_modules/graphql-http/lib/index.d.mts, there is no .js extension.

export * from './common';
export * from './handler';
export * from './client';
export * from './audits';

It may works correctly by changing the following code:

export * from './common.js';
export * from './handler.js';
export * from './client.js';
export * from './audits/index.js';

Support for graphiql

I was looking forward to starting to learn graphql and migrate from rest for my a personal project. Every other tutorial in the realm of NodeJS and Express recommend to use express-graph but it is deprecated and this module is recommend. However, I noticed one feature seems to be missing, graphiql. This isn't a dealbreaker but it would be nice to have this feature in graphql-http.

Unable to migrate from express-graphql: loads forever

Screenshot
image
image

Expected Behaviour
Should return

{
    "data": {
        "hello": "world"
    }
}

Actual Behaviour
Check screenshot, loads forever.

Debug Information
I used 2 code snippets: one with express-graphql, the other graphql-http

const express = require("express")
const {createHandler} = require('graphql-http');
const { GraphQLSchema, GraphQLObjectType, GraphQLString } = require("graphql");

const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    name: 'Query',
    fields: {
      hello: {
        type: GraphQLString,
        resolve: () => 'world',
      },
    },
  }),
});

const app = express()
  app.use(
  "/graphql",
  createHandler({
    schema
  })
)
app.listen(4000)
console.log("Running a GraphQL API server at http://localhost:4000/graphql")
const express = require("express")
const { graphqlHTTP } = require("express-graphql")
const { GraphQLSchema, GraphQLObjectType, GraphQLString } = require("graphql");
const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    name: 'Query',
    fields: {
      hello: {
        type: GraphQLString,
        resolve: () => 'world',
      },
    },
  }),
});

const app = express()
app.use(
  "/graphql",
  graphqlHTTP({
    schema: schema
  })
)
app.listen(4000)
console.log("Running a GraphQL API server at http://localhost:4000/graphql")

Further Information
I'm with node v16.16.0
package.json

{
  "name": "demo",
  "version": "1.0.0",
  "description": "demo",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "license": "ISC",
  "dependencies": {
    "express": "^4.18.2",
    "express-graphql": "^0.12.0",
    "graphql-http": "^1.18.0"
  }
}

Allow Deno to clean up leaked test resources

Screenshot

SHOULD use 4xx or 5xx status codes on document validation failure when accepting application/graphql-response+json => ./test.ts:9:8
error: AssertionError: Test case is leaking 1 resource:

 - A fetch response body (rid 380) was created during the test, but not consumed during the test. Consume or close the response body `ReadableStream`, e.g `await resp.text()` or `await resp.body.cancel()`.

    at assert (ext:deno_web/00_infra.js:353:11)
    at resourceSanitizer (ext:cli/40_testing.js:417:5)
    at async Object.exitSanitizer [as fn] (ext:cli/40_testing.js:435:7)
    at async runTest (ext:cli/40_testing.js:840:5)
    at async runTests (ext:cli/40_testing.js:1098:20)

Expected Behaviour

It should be possible to use the server audits in Deno.test() in a way that does not leak resources.

Actual Behaviour

As discussed in #63 (comment), the tests leak resources.
I am not sure why, but the fix I added to the PR now does not work (fully) in my project.

Debug Information

The following run shows what happens without any cleanup: https://github.com/nuwave/lighthouse/actions/runs/4488866245/jobs/7893989167.

With a cleanup step, some portion of the tests is fixed (I think the failing ones), but others still leak: https://github.com/nuwave/lighthouse/actions/runs/4488817464/jobs/7893880714.

Further Information

Here is the link to the PR where I try to run the audit in my project: nuwave/lighthouse#2359.

Add to the context values the response of the route, because it is usefull for set cookies for example.

Story

As a user or client or server

I want some feature

I want to add to the context values the response of the route, because it is usefull for set cookies for example.

So that some value

I want to add to the context values the response of the route, because it is usefull for set cookies for example.

Acceptance criteria

Something like this:

createHandler({
  schema,
  context: (req, res, params) => ({ req, res, params })
})

Deprecate old versions of `graphql-http`

The npm package of graphql-http had a few releases before. Deprecate all of them before releasing v1.

npm deprecate graphql-http@"< 1.0.0" "This package has a new owner and has completely changed as of v1! Please go to https://github.com/enisdenjo/graphql-http for more info."

UTF-8 body corruption

Expected Behaviour
One expects the default/fallback behaviour to correctly assemble UTF-8 multibyte characters in the request body.

Actual Behaviour
The default/fallback behaviour incorrectly assembles requests that exceed the input stream chunk size. Multibyte characters that straddle chunks are incorrectly parsed, resulting in replacement characters or arbitrary single byte characters.

Example: https://github.com/graphql/graphql-http/blob/main/src/use/http.ts#L144-L146

Debug Information
Send an HTTP request with a variable assigned to a large number of fx "å" that exceeds the request body stream high-water mark. The value passed to the schema will be intermittently corrupted.

Further Information
It appears as though simply calling req.setEncoding("utf8"); is enough to address the issue.

Response containing errors parsing variables is nested twice

Screenshot
Screenshot 2023-01-18 at 13 28 46

Expected Behaviour
I expected the error response to be structured like this:

{
    "errors": [
        {
            "locations": [
                {
                    "column": 8,
                    "line": 1
                }
            ],
            "message": "Variable \"$input\" got invalid value \"foo\"; Int cannot represent non-integer value: \"foo\""
        }
    ]
}

Actual Behaviour
but instead it was nested twice like so:

{
    "errors": [
        {
            "errors": [
                {
                    "locations": [
                        {
                            "column": 8,
                            "line": 1
                        }
                    ],
                    "message": "Variable \"$input\" got invalid value \"foo\"; Int cannot represent non-integer value: \"foo\""
                }
            ]
        }
    ]
}

Debug Information
Minimal example to reproduce:

Code:

const { GraphQLSchema, GraphQLObjectType, GraphQLInt } = require("graphql");

const express = require("express");
const { createHandler } = require("graphql-http/lib/use/express");

const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    name: "Query",
    fields: {
      hello: {
        type: GraphQLInt,
        args: {
          input: {
            type: GraphQLInt,
          },
        },
      },
    },
  }),
});

const app = express();
app.all("/graphql", createHandler({ schema }));

app.listen({ port: 4000 });
console.log("Listening to port 4000");

Send a query such as:

query ($input: Int) {
  hello(input: $input)
}

with variables:

{ "input": "foo" }

At first glance after briefly debugging it appears as though the error is here in the makeResponse function.

Further Information
The nesting format shown above under the "Expected Behaviour" section is the response that is returned by other GraphQL server frameworks such as express-graphql and graphql-yoga. Other errors returned by graphql-http are also not nested twice, such as when sending the following query against the example above.

Query

{
  hello(input: "foo")
}

Response:

{
    "errors": [
        {
            "locations": [
                {
                    "column": 16,
                    "line": 1
                }
            ],
            "message": "Int cannot represent non-integer value: \"foo\""
        }
    ]
}

Responses from createHandler in express are not returned

I tried to implement the code sample for express in order to migrate away from express-graphql. The express-graphql version works and returns a response, but the http-graphql version does not respond.

Code:

import * as express from 'express';
import { graphqlHTTP } from 'express-graphql';
import { GraphQLObjectType, GraphQLSchema, GraphQLString } from 'graphql';
import { createHandler } from 'graphql-http/lib/use/express';

const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    name: "Query", 
    fields: {hello: {type: GraphQLString, resolve: () => "hello"}}
  })
});
const app = express();

// express-graphql implementation
app.use('/graphql', graphqlHTTP({ schema: schema }));

// graphql-http express implementation
app.all('/graphql2', createHandler({ schema }));
app.listen(4000);

The I use curl:

curl http://localhost:4000/graphql --data-urlencode "query=query Q { hello }"
{"data":{"hello":"hello"}}

curl http://localhost:4000/graphql2 --data-urlencode "query=query Q { hello }"

Expected Behaviour
A response of {"data":{"hello":"hello"}} for both /graphql and /graphql2.

Actual Behaviour
Only /graphql (the express-graphql implementation) returns any response.

Version: 1.17.1
Node version: 16.14.0

Graphiql:true not working - {"errors":[{"message":"Missing query"}]}

Created new fresh project followed steps from provided documentation and I set graphiql:true and hit localhost:3001/graphql from browser so it's just showing following error instead graphqlUI.

{"errors":[{"message":"Missing query"}]}

`const express = require('express');
const app = express();
const port = 3001;
const { createHandler } = require('graphql-http/lib/use/express');

const { GraphQLSchema, GraphQLObjectType, GraphQLString } = require('graphql');

const schema = new GraphQLSchema({
query: new GraphQLObjectType({
name: 'Query',
fields: {
hello: {
type: GraphQLString,
resolve: () => 'world',
},
},
}),
});

app.get('/', (req, res) => {
res.send('Hello World!')
})

// Create a express instance serving all methods on /graphql
app.all('/graphql', createHandler({ schema,graphiql:true }));

app.listen(port, () => {
console.log(Example app listening on port ${port})
})`

v1.5.0 and 1.6.0 not working in module environment

Screenshot
image

Expected Behaviour
I expected it to works :)

Actual Behaviour
but instead it did this.

Debug Information
Just install latest version and used it with vite.

Further Information
Obviously, something is wrong with bunling - in lib folder there is no audits.mjs, so it should be audits/index.mjs in reexport

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.