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

feat: support for GET method for existing servers #180

Merged
merged 13 commits into from
Jan 19, 2017

Conversation

DxCx
Copy link
Contributor

@DxCx DxCx commented Oct 20, 2016

TODO:

  • Support for Express/Connect
  • Support for HAPI
  • Support for KOA
  • Fix Coverage (waiting implementation approval)
  • More tests? (need ideas :))
  • Documentation updates? (@helfer?)
  • Update CHANGELOG.md with your change (include reference to issue & this PR)
  • Make sure all of the significant new logic is covered by tests
  • Rebase your changes on master so that they can be merged easily
  • Make sure all tests and linter rules pass

Closes #121 , #186

@DxCx DxCx changed the title feat: support for GET method for existing servers feat: support for GET method for existing servers (WIP) Oct 20, 2016
@DxCx
Copy link
Contributor Author

DxCx commented Oct 26, 2016

@helfer @stubailo any update on this?

@helfer
Copy link
Contributor

helfer commented Oct 27, 2016

@DxCx Thanks, I'll review it before the weekend!

Copy link
Contributor

@helfer helfer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really great, I just had a few comments. I think we should keep the readme as simple as possible, and try to find a good name for the variable that's now called buffer.

After that, I think it will be sufficient to add just enough tests on the branches to make sure that each branch is covered. Once the PR is ready to be merged, I'll make a corresponding PR to the docs and link it here.

@@ -43,7 +43,23 @@ app.use('/graphql', bodyParser.json(), apolloExpress({ schema: myGraphQLSchema }
app.listen(PORT);
```

### Connect
### Express ( GET )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need separate instructions for GET and POST? I think we could just keep the old ones and explain that you don't need bodyparser with GET (which people can figure out, if they want).

Alternatively, we could comment the lines in the code that enable POST requests and GET requests, and then users can comment out the lines that they don't want/need.

@@ -42,33 +42,48 @@ export function graphqlExpress(options: GraphQLOptions | ExpressGraphQLOptionsFu
}

const formatErrorFn = optionsObject.formatError || graphql.formatError;
let buffer;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we call this requestPayload or something else that's more descriptive than buffer?


switch ( method ) {
case 'get':
return reply(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should document the fact that you cannot send batched queries with a GET request.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack, Where?
i just think that opening batching for GET is going to get monstrous URLs..

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but I don't think monstrous URLs should be our problem. There's a real risk for that already with normal queries. Most servers don't support URLs longer than 2000 characters, and I think even the introspection query might be longer than that. But that's really not something we should worry about. Maybe we can just put a warning in the README.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a good reason (from the server's perspective) not to allow batched requests via GET?

}

function getGraphQLParams(payload, isBatch, reply) {
function getGraphQLParams(buffer, isBatch, reply) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why rename this variable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to match to the code above it.
i can use requestPayload just like you suggested above

break;
case 'GET':
if ( !req.query ) {
res.statusCode = 500;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't that be a 400?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i just kept the same error code as post.
do you prefer it will be 400?

@DxCx
Copy link
Contributor Author

DxCx commented Nov 14, 2016

hi @helfer just seen your comments, i've replied on some and +1 on some.
please answer and i'll fix and rebase :)

break;
case 'GET':
if ( !req.query ) {
res.statusCode = 500;
Copy link
Contributor Author

@DxCx DxCx Nov 14, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not outdated actually.
i kept the same error code as POST.
@helfer, do you prefer it will be 400?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think 400 is better, because in the case of GET, it means a request was sent without a query, which is definitely not an internal server error. Although... that reminds me that we should also think about how prepared queries would work with GET. I definitely think they should be supported as well, so either this test is in the wrong place, or prepared queries should be a middleware that adds the query to the request before it hits graphql-server.

Copy link
Contributor Author

@DxCx DxCx Dec 1, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ohhh
i think you are abit confused (express <-> graphql naming coalition) :)

if you will take a deeper look, req.query for GET is equal to req.body of POST.
which means, in req.query you will get all the query params as key value.
(?key=value&seckey=value) will become:

{
  "key": "value",
  "seckey": "value",
}

therefore, if i was checking req.query.query, you were correct on your assumption.
is it more clear now? do you still think it should be 400 and not 500?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DxCx right, but you're checking req.query. If that's not present, it means it wasn't supplied by the user. In that case I would expect a 400, not a 500.

@DxCx
Copy link
Contributor Author

DxCx commented Nov 20, 2016

@helfer / @stubailo how do we progress?
is the implementation looks ok?
there are still unresolved review notes..

as far as i can see we need to extend testings to coverage all new logics
and we are good to go.

@helfer
Copy link
Contributor

helfer commented Nov 29, 2016

@DxCx looks 99% good to me. Let's add tests and then merge this. The PR has certainly been waiting for long enough!

@helfer
Copy link
Contributor

helfer commented Dec 13, 2016

@DxCx can you check off all the boxes that can be checked off, and then tell me what else needs to be done before we can merge this? I think GET support would be a nice present for the end of the year 😄

@DxCx
Copy link
Contributor Author

DxCx commented Dec 13, 2016

i still have work to do here, hoped someone else who needs the feature will take it from there.
anyway, i'll try to make it before the end of the year :D
can you take the documentation while i'll finish testing?

@helfer
Copy link
Contributor

helfer commented Dec 13, 2016

@DxCx okay, sounds good. I think someone else could definitely help or even finish it completely, but for that you should first write down a more detailed list of what still needs to be done. I don't think it would take too long to write that down. 🙂

@DxCx
Copy link
Contributor Author

DxCx commented Dec 13, 2016

just make sure all new code is covered by spec file,
and maybe add some more edge cases to the test suite case that is relevant to get (just need to think of some)

@DxCx DxCx changed the title feat: support for GET method for existing servers (WIP) feat: support for GET method for existing servers Dec 16, 2016
@DxCx
Copy link
Contributor Author

DxCx commented Dec 16, 2016

hi @helfer we are ready on my side.

Copy link
Contributor

@helfer helfer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot @DxCx! I think if we want to add more tests, we can always do that later. I'd rather not hold this up any longer for no good reason.

One thing we might want to consider adding is a check that makes sure GET requests don't contain mutations. express-graphql does that, and I think it's a neat little feature.

@nnance @HriBB could you take a minute to review the hapi and Koa parts respectively?


switch ( method ) {
case 'get':
return reply(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a good reason (from the server's perspective) not to allow batched requests via GET?

@helfer helfer requested a review from nnance December 19, 2016 14:21
@DxCx
Copy link
Contributor Author

DxCx commented Dec 20, 2016

cool.

Yeah i think we spoke about it before (either here or on slack)
but, giving the ability to create batched requests over query will create monstrous urls.
i think that at least for start we should block it,
then we can experiment more with it and understand how to allow this in the best way.

@DxCx
Copy link
Contributor Author

DxCx commented Dec 20, 2016

i did not understand why not allowing mutation via GET?

@helfer
Copy link
Contributor

helfer commented Dec 21, 2016

@DxCx The reason express-graphql doesn't allow mutations over GET is that GET requests in HTTP aren't supposed to have any side-effects. Mutations have side-effects by definition, so express-graphql doesn't allow mutations via GET.

@DxCx
Copy link
Contributor Author

DxCx commented Dec 22, 2016

Ok @helfer, sounds right. so you want me to block mutation for all GET requests?

@DxCx
Copy link
Contributor Author

DxCx commented Jan 12, 2017

@helfer?

@helfer
Copy link
Contributor

helfer commented Jan 12, 2017

@DxCx sorry I dropped the ball on this one. Yes, I think blocking mutations on GET would be good, just to match the behavior of express-graphql. Once you're done with that, please ping me on slack and I will take the PR from there and make sure it gets merged soon. Thanks a lot!

@DxCx
Copy link
Contributor Author

DxCx commented Jan 12, 2017

@helfer, no problem, so, we should return 405 error and header says that only POST is allowed..
i guess we should 'lock' get for query and not explicitly block mutation, do you agree?
if so will take care of it in the next 24 hours ;)

@DxCx
Copy link
Contributor Author

DxCx commented Jan 13, 2017

@helfer , please review the commits from today (the rest is just rebase).
i've moved http logic into core package, then added guard for non-query on GET.

@@ -68,6 +70,13 @@ export async function runHttpQuery(handlerArguments: Array<any>, request: HttpQu

let responses: Array<ExecutionResult> = [];
for (let requestParams of requestPayload) {
if ( isGetRequest && !requestParams.query.trim().startsWith('query')) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the spec the query keyword is optional. I know it's annoying, but that's how it is. So we'll have to check here whether it's an anonymous query that starts with {.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, the query isn't necessarily the first thing in the document right? For example:

fragment X on Y { ... }

{ ... }

Is also a valid query.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would check for "document doesn't contain the keyword mutation outside of all brackets"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@helfer => i was already figured it out, and actually, you were reviewing outdated chunk, which this was already fixed.
@stubailo => about the fragment, this is really usecase i didn't take into consideration,
i'll try to use GraphQL Parser instead to get the exact operation GraphQL will try to execute.

@DxCx
Copy link
Contributor Author

DxCx commented Jan 18, 2017

ok @stubailo @helfer
please check latest commit which is using GraphQL parser to determinate the query operation.

@helfer
Copy link
Contributor

helfer commented Jan 19, 2017

@DxCx Perfect, I think parsing the query is great. And thanks to how the core works it won't be parsed twice. I'll update the docs and roll a new release!

@helfer helfer merged commit 454e2a4 into apollographql:master Jan 19, 2017
@helfer helfer removed the ready label Jan 19, 2017
@DxCx DxCx deleted the get-support branch January 19, 2017 07:32
trevor-scheer pushed a commit that referenced this pull request Oct 17, 2022
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
trevor-scheer pushed a commit that referenced this pull request Oct 17, 2022
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
trevor-scheer pushed a commit that referenced this pull request Oct 19, 2022
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants