Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is application/graphql supported? #48

Closed
nevir opened this issue Jul 13, 2016 · 21 comments
Closed

Is application/graphql supported? #48

nevir opened this issue Jul 13, 2016 · 21 comments

Comments

@nevir
Copy link
Contributor

nevir commented Jul 13, 2016

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."
    }
  ]
}
@stubailo
Copy link
Contributor

As far as I know, application/graphql is not a thing people usually do - why not use application/json?

@nevir
Copy link
Contributor Author

nevir commented Jul 13, 2016

I was playing around w/ a few modules, one of which expected it to be supported (graphql-tester)

@stubailo
Copy link
Contributor

Yeah, that seems super weird to be honest. I don't think it's to anyone's advantage to introduce new MIME types? It's nowhere in the spec or any implementations that I'm aware of.

@helfer helfer closed this as completed Jul 26, 2016
@nevir
Copy link
Contributor Author

nevir commented Jul 26, 2016

express-graphql does support it

@helfer
Copy link
Contributor

helfer commented Jul 26, 2016

@nevir Which version of apollo-server did you use? The current release uses express-graphql under the hood, so I find it hard to believe that it wouldn't work. The release candidate doesn't parse queries automatically, so you'd have to do that yourself by telling body-parser to parse application/graphql.

@nevir
Copy link
Contributor Author

nevir commented Jul 27, 2016

I was on 0.1.5 at the time - haven't tried since (we have no good use case for application/graphql now that we understand what's going on :P)

@helfer
Copy link
Contributor

helfer commented Jul 27, 2016

Hm, that's strange. It should definitely work because 0.1.5 passes the same tests as express-graphql.

@tony19
Copy link

tony19 commented Jan 5, 2017

The current release uses express-graphql under the hood, so I find it hard to believe that it wouldn't work.

Hmm. I didn't find any reference to express-graphql in graphql-server-express's code/manifest.

@helfer I can confirm that graphql-server-express 0.4.3 (used by the frontpage-server demo) does not support Content-Type: application/graphql.

application/json works:

$ curl -X POST http://localhost:8080/graphql -d '{"query": "query test { posts { title } }" }' -H 'Content-Type: application/json' 
{"data":{"posts":[{"title":"Introduction to GraphQL"},{"title":"GraphQL Rocks"},{"title":"Advanced GraphQL"}]}}%

but not application/graphql:

$ curl -X POST http://localhost:8080/graphql -d '{ posts { title } }' -H 'Content-Type: application/graphql' 
{"errors":[{"message":"Cannot read property 'definitions' of undefined"}]}% 

It was an easy switch to express-graphql to get that header to work, and its simpler interface is a bonus.

@stubailo
Copy link
Contributor

stubailo commented Jan 5, 2017

Content type application/graphql isn't great because it doesn't support variables. I would suggest just not using it.

@tony19
Copy link

tony19 commented Jan 5, 2017

@stubailo Can you clarify? Variables work for me.

@stubailo
Copy link
Contributor

stubailo commented Jan 5, 2017

How do you pass them, as query parameters?

@tony19
Copy link

tony19 commented Jan 5, 2017

Sorry, I misunderstood what GraphQL variables were until I read the docs.

@stubailo
Copy link
Contributor

stubailo commented Jan 5, 2017

Right - variables are a critical part of the GraphQL specification, so it's really surprising that the "official" HTTP server middleware supports a transport that doesn't have any ability to use them.

@jsamr
Copy link

jsamr commented Feb 1, 2017

application/graphql is mentioned in the official guide

@helfer
Copy link
Contributor

helfer commented Feb 1, 2017

@sveinburne I would find it interesting to know why they recommend supporting those two use-cases. If there's a good reason for it, I wouldn't be opposed to adding the same functionality in graphql-server.

Right now I think it was a mistake to come up with "application/graphql", thus I don't think graphql-server should support it. After all, Lee Byron said himself that when you're thinking of adding something but you're not sure you'll need it, then "you ain't gonna need it". So far I haven't heard a convincing argument for why anybody needs "application/graphql". I'd like to be enlightened though, so if someone knows, please tell me!

@stubailo
Copy link
Contributor

stubailo commented Feb 1, 2017

Yeah there was a discussion on some graphql.org issue about removing that recommendation and I didn't find any concrete arguments for why it exists.

@hulkish
Copy link

hulkish commented Aug 10, 2017

Would really appreciate this somehow being sought through. Personally, I think it's better if they just pick one... Only reason I suppose this is a value use case - is for GET requests, - since you can'tt send a post body with that request method?

@sleepycat
Copy link

@helfer maybe need is a strong word for application/graphql but I think it's a nice developer experience for testing and when using curl.
An example test:

describe('Server', () => {
  it('has GraphQL middleware mounted at /graphql', async () => {
    let server = new Server()
    let response = await request(server)
      .post('/graphql')
      .set('Content-Type', 'application/graphql; charset=utf-8')
      .send(`{ hello }`)

    expect(response.status).toEqual(200)
  })
})

and curl:

curl -v -H "Content-Type: application/graphql" -d "{ hello }"  "localhost:3000/graphql"

JSON is clunky for those simple cases and readability suffers. This obviously isn't a big thing, but it's still nice to have IMO.

@stubailo
Copy link
Contributor

If you want to run a GraphQL proxy, or handle requests in the middleware chain, multiple ways to send queries can be a big downside. You pretty much need both GET and POST, but the application/graphql method is more optional. You could always add an extra middleware to the chain to attach stuff to the request body to add support for other transports.

@kbrandwijk
Copy link

I have just released an Express body-parser that supports the application/graphql MIME type. It can be used as a drop-in replacement for the JSON body-parser. https://www.npmjs.com/package/body-parser-graphql 🎉

@btilford
Copy link

btilford commented Mar 3, 2020

Shouldn't the content type be something like application/graphql+json? I've got a situation where graphql is only going to be used in specific scenarios so application/json isn't specific enough.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants