简体   繁体   English

Apollo Server 作为 Nuxt 服务器中间件

[英]Apollo Server as Nuxt serverMiddleware

I've managed to have a express + Apollo Backend as a serverMiddleware in Nuxtjs.我已经设法在 Nuxtjs 中拥有一个 express + Apollo Backend 作为服务器中间件。 Everything works fine(auth, cache, datasources, queries, mutations) but now I'm trying to get subscriptions(websockets) running and its giving me a hard time.一切正常(身份验证、缓存、数据源、查询、突变),但现在我试图让订阅(websockets)运行,这给我带来了困难。

I tried this example https://www.apollographql.com/docs/apollo-server/data/subscriptions/#subscriptions-with-additional-middleware but even letting the httpServer listening didn't work.我试过这个例子https://www.apollographql.com/docs/apollo-server/data/subscriptions/#subscriptions-with-additional-middleware但即使让 httpServer 监听也没有用。

This is my API file which I require through the nuxt.config.js with '~/api/index' :这是我通过带有'~/api/index'的 nuxt.config.js 需要的 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
  }
}

Now my playground is giving me this error: "Could not connect to websocket endpoint ws://192.168.150.98:3000/api/graphql. Please check if the endpoint url is correct."现在我的操场给了我这个错误: "Could not connect to websocket endpoint ws://192.168.150.98:3000/api/graphql. Please check if the endpoint url is correct."

TypeDefs:类型定义:

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

Resolvers:解析器:

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]),
  },
}

First question here, thank u in advance!第一个问题在这里,提前谢谢你! :) :)

it can also be a little easier它也可以更容易一点

1. 1.

yarn add apollo-server-express

or或者

npm install apollo-server-express
  1. create file ./server/index.js创建文件 ./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. add in your nuxt.config.js添加你的 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`)
      },
    },
  }
}

I found a hacky way to achieve it , import the code as a nuxt module:我找到了一种实现它的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))
  })
}

Tho I'm now using a probably more stable way, using nuxt programmatically !我现在正在使用一种可能更稳定的方式,以编程方式使用 nuxt With hapi instead of express, since express is giving me trouble compiling and not showing the loading-screen(progress of building).使用 hapi 而不是 express,因为 express 给我编译和不显示加载屏幕(构建进度)带来了麻烦。 Just use npx create-nuxt-app and create an app with a hapi server backend.只需使用npx create-nuxt-app并创建一个带有 hapi 服务器后端的应用程序。

The code with hapi would look like this:带有 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))

Maybe i can help somebody也许我可以帮助某人

An easier way is to use the getMiddleware() method of Apollo Server Express:更简单的方法是使用 Apollo Server Express 的getMiddleware()方法:

Create a file under ./api/index.js :./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

and then register it in ./nuxt.config.js :然后在./nuxt.config.js注册:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM