-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Migrating from 1.0 to 2.0: How to add middleware? #1117
Comments
// Mount my middleware to run *before* Apollo which can break the request chain if required
app.use("/graphql", requireAuth, throttle);
// Mount Apollo middleware
await registerServer({ app, server: apolloServ }); |
@eugene1g Great! I solved this a slightly different way in rewriting my middleware and putting everything in the graphql context function instead. I ran into the problem of context not resolving promises though. (#1066, which you commented on already, thanks!). I know they aren't the same (middleware vs context), but for me it achieves roughly the same thing. Between the two, it seems like both require a bit of a hack to make it work. The double mounting middleware method requires you to overwrite the mount point and the context method (currently) requires the wrapper function you mentioned in #1066. Which of the two methods would you recommend? Right now it actually seems like the double mounting endpoint is less hacky. (and supports third-party express middleware out of the box.) |
FYI, I switched to using the double mounting method as stated above and it's working beautifully. |
I think Apollo Server is still figuring out the best way to plugin into existing app servers. If all you do is GraphQL, then it's an awesome experience out of the box. If you need it to be a piece of a larger app, then it's a bit messy - multiple express instances involved etc. For example, the above method of "double mounting" middleware only helps if you want to run middleware before Apollo, but I think there is no way to run anything after Apollo (without monkey patching) because it breaks the chain and the response. I expect they will figure it out soon! Personally, I use both methods. I put "http" stuff like auth into middleware and mount it before Apollo. I also use the async context function to do "business/app" stuff. For example, |
The double mounting makes sense. The one suggestion I would make is setting the path explicitly in the For middleware after Apollo, it can be added after the |
Nope, I don't have a real use-case for calling middleware after Apollo - it's just a "what-if". When I quickly tested by adding another middleware with 'app.use()' after |
Hello, @evans, |
@avirdz One workaround is to use the const myserver = new ApolloServer({
schema: executableSchema,
context: ({req}) => { return { res: req.res }},
formatError: formatResponseError
}); Then you can access |
Thanks a lot, I tried that before and it didn't work, I needed to use req.res instead of req.response 👍 |
@evans I'm mainly running into trouble regarding CORS middleware in version 2. In version 1 it worked out fine. Any ideas? |
I also would be careful about trying to over-simplify the setup. As mentioned above I agree that for standalone options thats fine. But for middleware scenario having magic function like registerServer is confusing to me.. why should I call listen on ApolloServer since its supposed to be just middleware. (I already spent hour trying to migrate middleware scenario from version 1 to version 2 and still does not work and have no idea how that would play if I want both http and https which I had before). I had similar experience with apollo-boost. I think just having boilerplate in doc to be copy&pasted is better than hiding that behind magic functions/objects/package. It does not make difference if newcomer has to install multiple packages and copy&paste more lines. It gets confusing once some of the customization needs to be done.. and developer has to replace the apollo-boost. So I actually preferred the previous more explicit middleware setup. |
@jardakotesovec We hear you! With the middleware, we've definitely run into issues with https #1155 and hot module reloading, accessing the underlying listeners #1137. The reality of @leovanhaaren You're able to pass a |
In the latest beta.11, we moved to an The new api should the implementor to understand what is going on under the hood without having to dig through the source. Subscriptions are now created in this manner: https://glitch.com/edit/#!/mountainous-suggestion?path=index.js:49:0 If there are still things we can do to improve the middleware api, I would love to hear them! |
@evans That was quick. Just updated and looks great. Thanks! |
@evans I was just looking yesterday at how I would integrate Apollo 2.0 into an existing hapi application, so the beta.11 change is very much appreciated! |
@evans It seems like if you wanted to mount multiple graphql endpoints on a server, it might cause some conflicting behavior, specifically around the health checks as it attaches global routes. |
Similar to the concern raised in #1117 (comment), we have a use case where we maintain multiple graphql endpoints (protected vs public APIs). Each of these endpoints have different schemas. What is the recommended approach in Apollo Server 2.0? |
I want to make a call using a request-scoped logger in middleware just before a response is returned to log success or otherwise. Per the docs, I would expect to be able to do:
(where the logger has been added to the request at an earlier stage.) However, with 2.0.0-rc.7, the loggingMiddleware is never called. What's the suggested way to achieve this? |
@lionkeng : One idea that was mentioned in ardatan/graphql-tools#323 and graphql/graphql-js#113, was controlling the visibility of portions of the schema, based on a role. If one could control the visibility of portions of the schema (not just their execution), then you could still have a single end point that provides both an admin and non-admin view of the same original API. I would also like to know what the recommended approach for Apollo server 2.0 is for migrating from multiple endpoints, each with different middleware. |
@lionkeng Were you able to get something working for multiple schemas? |
Hi @vjpr, we are still experimenting to see what works best.
|
Any other hints on this? Currently trying to change the response status code after the request has finished processing inside the GraphQL-layer but any |
I am loving the direction with the new Apollo server, as it makes it much easier for new developers to get started. My only ask is this, allow us to only apply the GraphQL middleware as you've done in const express = require('express');
const app = express();
// ...
const server = new ApolloServer({ schema, context });
// Only apply the GraphQL middleware, nothing else.
app.use('/graphql', express.json(), server.middleware.graphql);
// ... I think that gives the best solution for most existing implementations, and still allows the use of the "all-in-one" solution that's proposed already. Would love to get some feedback from the Apollo team on this 😄 |
I have the same problem but regarding with the express 404 middleware. Since apollo let the response pass, the res.end is executed twice. So i ended up doing this workaround: graphqlService.applyMiddleware({ app });
app.use((req, res, next) => {
if (res.headerSent === false) {
next(notFoundError());
} else {
res.end();
}
}); |
seems like this PR fix this issue #1436 Could you verify and close if the issue is not happening anymore with v2.0.2 |
I agree that this would be better for us that need to customize the endpoint further beyond what is provided by default. It was provided in an earlier version and worked great. |
Hi,
I am using these packages
Can you help? |
If u ll b using express middleware, u should use apollo-server-express The information on Apollo Docs can be found under the heading of "Adding Additional Middleware to Apollo Server 2". Basically, it is just app.use(...) before using applyMiddleware call |
We offer apollo-server-* for integrations which allow for customizing the middleware as part of an overall other server framework! |
I'm using express middleware on before my graphql endpoint to authenticate and do some other stuff. How do I do that in 2.0?
I had apollo-server-express configured in 1.0 like this:
Looking at how I'm supposed to configure
ApolloServer()
and useregisterServer()
it makes sense until I want to add my own middleware. There doesn't seem to be a place to add this middleware.The text was updated successfully, but these errors were encountered: