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

Support async schema #1661

Closed
2 of 5 tasks
moimael opened this issue Sep 13, 2018 · 4 comments
Closed
2 of 5 tasks

Support async schema #1661

moimael opened this issue Sep 13, 2018 · 4 comments
Labels
⛲️ feature New addition or enhancement to existing solutions

Comments

@moimael
Copy link

moimael commented Sep 13, 2018

  • has-reproduction
  • feature
  • docs
  • blocking
  • good first issue

Hi,

I tried to migrate our graphql proxy to apollo-server v2 and got an issue reported by TS. We are creating the schema manually (for schema stitching) and make use of the makeRemoteExecutableSchema function. We chose to introspect the schema at runtime so our returned schema is async. It used to work perfectly fine with v1 but now the ApolloServer schema option is not accepting it anymore.

It does work if I wait for my schema to resolve first and then setup the server but it's not very nice.

Could we add support for async schema back ?

Thanks !

@ghost ghost added ✋ blocking Prevents production or dev due to perf, bug, build error, etc.. 🌹 has-reproduction ❤ Has a reproduction in Glitch, CodeSandbox or Git repository. labels Sep 13, 2018
@sbrichardson
Copy link
Contributor

sbrichardson commented Sep 14, 2018

One option is to extend the ApolloServer class with a customized applyMiddleware method.
I was able to resolve for the time being using this strategy. See an example in this comment:

#1308 (comment)

In the example, you can't see async/await, but it is resolving a promise behind the scenes.

@sbrichardson
Copy link
Contributor

sbrichardson commented Sep 14, 2018

Here's a more complete example with the playground code included.
I omitted a few details from my own logic, noted below.

It's basically building a custom schema on each request from a cache, instead of just passing the schema from the ApolloServer class instance when it started initially. This isn't using subscriptions currently, I haven't needed/tested with that yet.

import { renderPlaygroundPage } from '@apollographql/graphql-playground-html'
import accepts from 'accepts'
import { ApolloServer, makeExecutableSchema } from 'apollo-server-express'
import { graphqlExpress } from 'apollo-server-express/dist/expressApollo'

class CustomServer extends ApolloServer {
  applyMiddleware({ app, path }) {
    app.use(path, async (req, res, next) => {
      if (this.playgroundOptions && req.method === 'GET') {
        // perform more expensive content-type check only if necessary
        // XXX We could potentially move this logic into the GuiOptions lambda,
        // but I don't think it needs any overriding
        const accept = accepts(req)
        const types = accept.types()
        const prefersHTML =
          types.find(x => x === 'text/html' || x === 'application/json') ===
          'text/html'

        if (prefersHTML) {
          const playgroundRenderPageOptions = {
            endpoint: path,
            subscriptionEndpoint: this.subscriptionsPath,
            ...this.playgroundOptions,
          }
          res.setHeader('Content-Type', 'text/html')
          const playground = renderPlaygroundPage(playgroundRenderPageOptions)
          res.write(playground)
          res.end()
          return
        }
      }

      const {
        // ...omitted for example
      } = req.body

      const { schema: _remove, context: _context, ...serverObj } = this

      return graphqlExpress(
        super.createGraphQLServerOptions.bind({
          ...serverObj,
          graphqlPath: path,
          schema: await makeExecutableSchema(
            // ...omitted for example
          ),
          context: {
            // ...omitted for example
            request: req,
          },
        })
      )(req, res, next)
    })
  }
}

export default CustomServer

@moimael
Copy link
Author

moimael commented Mar 8, 2019

Would love to have that, it is currently making the upgrade painful

EDIT: Also it doesn't reload the schema when the schema change since it's resolved before the server starts so you have to restart the server

@abernix abernix added ⛲️ feature New addition or enhancement to existing solutions and removed ✋ blocking Prevents production or dev due to perf, bug, build error, etc.. 🌹 has-reproduction ❤ Has a reproduction in Glitch, CodeSandbox or Git repository. labels Jul 4, 2019
@abernix abernix changed the title V2 doesn't allow for async schema in ApolloServer Support async schema Jul 4, 2019
@jbaxleyiii jbaxleyiii added the 🚧👷‍♀️👷‍♂️🚧 in triage Issue currently being triaged label Jul 8, 2019
@jbaxleyiii
Copy link
Contributor

@moimael initial support this is in progress and will also be part of Apollo Server 3.0!

@abernix abernix removed 🚧👷‍♀️👷‍♂️🚧 in triage Issue currently being triaged labels Jul 9, 2019
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
⛲️ feature New addition or enhancement to existing solutions
Projects
None yet
Development

No branches or pull requests

4 participants