Apollo Server 作为 Nuxt 服务器的中间件
Apollo Server as Nuxt serverMiddleware
我已经设法在 Nuxtjs 中拥有一个 express + Apollo 后端作为服务器中间件。
一切正常(身份验证、缓存、数据源、查询、突变),但现在我正在尝试获取订阅(websockets)运行,这让我很困难。
我试过这个例子 https://www.apollographql.com/docs/apollo-server/data/subscriptions/#subscriptions-with-additional-middleware 但即使让 httpServer 监听也没有用。
这是我的 API 文件,我需要通过 nuxt.config.js 和 '~/api/index'
:
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]),
},
}
这里是第一个问题,先谢谢你了! :)
我找到了一个 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))
也许我可以帮助别人
也可以简单一点
1.
yarn add apollo-server-express
或
npm install apollo-server-express
- 创建文件 ./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
- 加入你的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`)
},
},
}
}
更简单的方法是使用 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' }],
}
我已经设法在 Nuxtjs 中拥有一个 express + Apollo 后端作为服务器中间件。 一切正常(身份验证、缓存、数据源、查询、突变),但现在我正在尝试获取订阅(websockets)运行,这让我很困难。
我试过这个例子 https://www.apollographql.com/docs/apollo-server/data/subscriptions/#subscriptions-with-additional-middleware 但即使让 httpServer 监听也没有用。
这是我的 API 文件,我需要通过 nuxt.config.js 和 '~/api/index'
:
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]),
},
}
这里是第一个问题,先谢谢你了! :)
我找到了一个 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))
也许我可以帮助别人
也可以简单一点
1.
yarn add apollo-server-express
或
npm install apollo-server-express
- 创建文件 ./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
- 加入你的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`)
},
},
}
}
更简单的方法是使用 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' }],
}