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

return next() on route completion #462

Closed
chemdrew opened this issue Jul 17, 2017 · 13 comments
Closed

return next() on route completion #462

chemdrew opened this issue Jul 17, 2017 · 13 comments

Comments

@chemdrew
Copy link
Contributor

In order to chain pre and post completion middleware the next keyword must be called in all steps along the way. This is mostly valid for Express projects as a way to simulate Restify's 'after' event.

app.use(<pre-execution middleware>);

app.use('/graphql', graphqlExpress({ schema: MyGraphQLSchema }));

app.use(<post-execution middleware>); // my use case: log response without overriding res.end

I'll attach a PR to this issue as well, since it's a super simple and unobtrusive change and we can discuss from there!

Thanks

@freiksenet
Copy link
Contributor

Merged. Thanks a lot!

@freiksenet
Copy link
Contributor

Reopening. There seems to be a disagreement whether that's the best practice for middlewares that are endpoints. However I do feel the use case that @chemdrew made is valid.

Pinging @Friss and @RAFREX

@freiksenet freiksenet reopened this Jul 24, 2017
@Friss
Copy link

Friss commented Jul 24, 2017

I agree that it's a valid use case but only if you know it will happen.

If it was configurable and off by default I think it would be a good change.

@chemdrew
Copy link
Contributor Author

I’m good with it being configurable, that makes sense to me. At least then the behavior is explicit.

If we make this change here we should also take a look at the restify package as well

@rafgraph
Copy link

I agree w/ @Friss - it's a valid use case. I think making it configurable and off by default is a good solution.

@sheerun
Copy link

sheerun commented Oct 23, 2017

exactly, for now it's impossible to run any post-execution middleware without overriding res..

@chemdrew
Copy link
Contributor Author

I was working on adding the configurable flag for this but it made the API a tad ugly and more confusing without the background of this. Another option I'd like to suggest, which will be more work but cleaner, is that graphqlExpress returns a promise.

Then the user can either choose to use that or ignore it and chain middleware like so:

app.use(<pre-execution middleware>);

const graphqlHandler = (req, res, next) => {
  const graphqlHTTPHandler = graphqlExpress({ schema: MyGraphQLSchema });
  return graphqlHTTPHandler(req, res).then(() => {
    next();
  }).catch(next);
};

app.use('/graphql', graphqlHandler);

app.use(<post-execution middleware>); // my use case: log response without overriding res.end

@govorov
Copy link

govorov commented Dec 5, 2017

The same case with Koa.
GraphQL is not always an endpoint. For example, I want to map GraphQL errors to http status codes after query execution.
Now it's impossible to run any post-process middleware:

// this won't work as expected

// postprocessor:
export const myPostProcessor = async (ctx, next) => {
    // my custom magic happens next...
    await next();
};

// routing:
routes.post(apiEntrypointPath, ensureAuthenticated, bodyParser(), myPostProcessor, graphQlMiddleware);

That said, there's a workaround -- change routes.post parameters order and call await next(); before postprocessing inside postprocessor source code. But I find that ugly, as from my point of view, as middleware order and execution order don't match anymore, which I find irrational.

+1 for having that option configurable. Thank you.

@the-noob
Copy link

the-noob commented Mar 8, 2019

I've recently moved from express-graphql to apollo-server-express just to see the solution for this is to go back and customise the graphqlExpress call ( + setting up Playground).
This not be good.

I need to close my AMQP channels after everything.

@jbaxleyiii
Copy link
Contributor

@chemdrew @the-noob we are going to be improving the relationship between integrations and Apollo Server in the next version (Apollo Server 3) which will make this possible. I'm going to close this issue as its goals are tracked in the #2360

@timbrownsf
Copy link

Is there still no way to apply a post completion middleware on a graphql endpoint?

@cuzzlor
Copy link

cuzzlor commented Jul 27, 2020

You can using a Plugin

@timbrownsf
Copy link

timbrownsf commented Jul 27, 2020

Yes, found the answer in this thread. For future readers, beware, the official answer using didEncounterErrors in the thread doesn't work for many, you must jump to the issue comment I linked.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 20, 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 a pull request may close this issue.