【问题标题】:Apollo Server as Nuxt serverMiddlewareApollo Server 作为 Nuxt 服务器中间件
【发布时间】:2020-05-13 01:55:12
【问题描述】:

我已经设法在 Nuxtjs 中拥有一个 express + Apollo 后端作为 serverMiddleware。 一切正常(身份验证、缓存、数据源、查询、突变),但现在我正试图让订阅(websockets)运行,这让我很难过。

我试过这个例子https://www.apollographql.com/docs/apollo-server/data/subscriptions/#subscriptions-with-additional-middleware,但即使让httpServer监听也没有用。

这是我通过 nuxt.config.js 使用 '~/api/index' 需要的 API 文件:

module.exports = async () => {
  const app = require('express')()
  const server = await require("./apollo")() // apollo-server-express w/ typeDefs and resolvers

  // apply Apollo to Express
  server.applyMiddleware({ app });
  console.log(`???? ApolloServer ready at ${server.graphqlPath}`);

  const httpServer = http.createServer(app);
  server.installSubscriptionHandlers(httpServer);
  console.log(`???? ApolloSubscriptions ready at ${server.subscriptionsPath}`);

  return {
    path: '/api',
    handler: httpServer
  }
}

现在我的游乐场给了我这个错误:"Could not connect to websocket endpoint ws://192.168.150.98:3000/api/graphql. Please check if the endpoint url is correct."

类型定义:

type Subscription {
  postAdded: Post
}
type Post {
  author: String
  comment: String
}
type Query {
  posts: [Post]
}
type Mutation {
  addPost(author: String, comment: String): Post
}

解析器:

Query: {
  posts(root, args, context) {
    return Posts;
  }
}
Mutation: {
  addPost(root, args, context) {
    pubsub.publish(POST_ADDED, { postAdded: args });
    return Posts.add(args);
  }
},
Subscription: {
  postAdded: {
    // Additional event labels can be passed to asyncIterator creation
    subscribe: () => pubsub.asyncIterator([POST_ADDED]),
  },
}

这里的第一个问题,提前谢谢你! :)

【问题讨论】:

    标签: express websocket nuxt.js apollo subscription


    【解决方案1】:

    也可以轻松一点

    1.

    yarn add apollo-server-express
    

    npm install apollo-server-express
    
    1. 创建文件 ./server/index.js
    import { ApolloServer, gql } from 'apollo-server-express'
    
        // Construct a schema, using GraphQL schema language
    const typeDefs = gql`
      type Query {
        hello: String
      }
    `
    
    // Provide resolver functions for your schema fields
    const resolvers = {
      Query: {
        hello: () => 'Hello world!',
      },
    }
    
    const server = new ApolloServer({ typeDefs, resolvers })
    
    export default server
    
    1. 添加您的 nuxt.config.js
    import server from './server'
    
    export default {
    // ... your nuxt config stuff
    // ...
      hooks: {
        render: {
          async before({
            nuxt: {
              server: { app },
            },
          }) {
            await server.applyMiddleware({ app, path: '/api' })
            console.log(`? ApolloServer ready at /api`)
          },
        },
      }
    }
    

    【讨论】:

      【解决方案2】:

      我找到了一个 hacky 方法来实现它,将代码导入为 nuxt 模块:

      import http from 'http'
      
      export default function () {
        this.nuxt.hook('render:before', async () => {
          const server = require("./apollo")()
          
          // apply Apollo to Express
          server.applyMiddleware({ app: this.nuxt.renderer.app });
          console.log(`? ApolloServer ready at ${server.graphqlPath}`);
          
          const httpServer = http.createServer(this.nuxt.renderer.app);
          
          // apply SubscriptionHandlers to httpServer
          server.installSubscriptionHandlers(httpServer);
          console.log(`? ApolloSubscriptions ready at ${server.subscriptionsPath}`);
      
          // overwrite nuxt.server.listen()
          this.nuxt.server.listen = (port, host) => new Promise(resolve => httpServer.listen(port || 3000, host || 'localhost', resolve))
          
          // close this httpServer on 'close' event
          this.nuxt.hook('close', () => new Promise(httpServer.close))
        })
      }
      

      尽管我现在使用一种可能更稳定的方式,using nuxt programmatically! 使用 hapi 而不是 express,因为 express 给我编译和不显示加载屏幕(构建进度)带来了麻烦。 只需使用 npx create-nuxt-app 并创建一个带有 hapi 服务器后端的应用程序。

      带有 hapi 的代码如下所示:

      const consola = require('consola')
      const Hapi = require('@hapi/hapi')
      const HapiNuxt = require('@nuxtjs/hapi')
      
      async function start () {
        const server = require('./apollo/index')()
        const app = new Hapi.Server({
          host: process.env.HOST || '127.0.0.1',
          port: process.env.PORT || 3000
        })
      
        await app.register({
          plugin: HapiNuxt
        })
        
        app.route(await require('./routes')())
        
        await server.applyMiddleware({
          app,
          path: '/graphql'
        });
        console.log(`? ApolloServer ready at ${server.graphqlPath}`);
        await server.installSubscriptionHandlers(app.listener)
        console.log(`? ApolloSubscriptions ready at ${server.subscriptionsPath}`);
      
        await app.start()
      
        consola.ready({
          message: `Server running at: ${app.info.uri}`,
          badge: true
        })
      }
      process.on('unhandledRejection', error => consola.error(error))
      start().catch(error => console.log(error))
      

      也许我可以帮助别人

      【讨论】:

        【解决方案3】:

        更简单的方法是使用 Apollo Server Express 的getMiddleware() 方法:

        ./api/index.js下创建一个文件:

        const { ApolloServer, gql } = require('apollo-server-express')
        const express = require('express')
        
        const typeDefs = gql`
          type Query {
            hello: String
          }
        `
        
        const resolvers = {
          Query: {
            hello: () => 'Hello world!',
          },
        }
        
        const server = new ApolloServer({ typeDefs, resolvers })
        const app = express()
        
        app.use(express.json())
        app.use(express.urlencoded({ extended: true }))
        app.use(server.getMiddleware())
        
        module.exports = app
        

        然后在./nuxt.config.js注册:

        {
          // other nuxt config ...
          serverMiddleware: [{ path: '/api', handler: '~/api/index.js' }],
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-01-13
          • 2021-03-24
          • 2021-04-18
          • 2020-10-23
          • 2021-05-11
          • 2019-08-27
          • 2019-06-08
          • 2019-05-19
          相关资源
          最近更新 更多