我在将 GraphQL 集成到 Node.js 应用程序中时遇到问题。 最初一切正常,但添加 notFoundHandler() 后,位于 localhost:3000/graphql 的 GraphQL 端点不再可访问。
这是我对这个问题的理解:
我正在寻求有效解决这一冲突的解决方案。
我的申请具体细节:
我考虑了潜在的方法:
我愿意接受以下方面的任何建议或见解:
任何指导将不胜感激!
为了更清晰地了解代码结构,我分享以下摘录:
package.json
{
"name": "gql4",
"version": "1.0.0",
"description": "",
"main": "www.mjs",
"scripts": {
"start": "nodemon www.mjs"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@apollo/server": "^4.10.0",
"cors": "^2.8.5",
"express": "^4.18.2",
"nodemon": "^3.0.2"
}
}
www.mjs
import {Application} from './app.mjs'
new Application();
schema.js
const {GraphQLObjectType,GraphQLSchema, GraphQLInt, GraphQLString} = require('graphql');
const RootQuery = new GraphQLObjectType({
name: 'RootQuery',
fields: {
blogs : {
type : new GraphQLObjectType({
name: "blogsType",
fields : {
id: {type: GraphQLInt},
title: {type: GraphQLString},
text: {type: GraphQLString}
}
}),
resolve: ()=>{
return {
id: 1,
title: "title of blog",
text: 'text of blog',
}
}
}
}
});
const graphQlSchema = new GraphQLSchema({
query: RootQuery
});
module.exports = {
graphQlSchema
};
notFound.handler.js
module.exports = function notFoundHandler(app){
app.use((req,res,next)=>{
res.status(404).json({
message: "Not Found Route"
})
})
}
app.mjs
import express from 'express';
import cors from 'cors';
import { ApolloServer } from '@apollo/server';
import { expressMiddleware } from '@apollo/server/express4';
import notFoundHandler from './notFound.handler.js';
import {graphQlSchema} from './schema.js';
const app = express();
class Application{
constructor(){
this.setExpress();
this.setConfigs();
this.setRoutes();
this.setGraphQL();
notFoundHandler(app);
}
setExpress(){
const PORT = 3020;
app.listen(PORT,()=>console.log(`Server is running on port ${PORT}`));
}
setConfigs(){
app.use(express.json());
app.use(express.urlencoded({extended:true}))
app.use(cors())
}
setRoutes(){
app.get('/',(req,res)=>res.json("Welcome"))
}
async setGraphQL(){
const server = new ApolloServer({
schema: graphQlSchema
})
await server.start();
app.use('/graphql',cors(),expressMiddleware(server));
}
}
export { Application }
作为第一个解决方案,我在 app.use('/graphql',cors(),expressMiddleware(server)); 之后调用 setGraphQL 方法中的 notFoundHandler(app)
效果很好,但我认为这不是最佳实践。
async setGraphQL(){
const server = new ApolloServer({
schema: graphQlSchema
})
await server.start();
app.use('/graphql',cors(),expressMiddleware(server));
notFoundHandler(app);
}
几小时后,我找到了另外两种方法来解决这个问题。
第一个解决方案:
app.mjs
constructor(){
this.setExpress();
this.setConfigs();
this.setRoutes();
(async()=>{
await this.setGraphQL();
this.setErrorHandler(app);
})()
}
(async()=>{...})():它使用箭头函数语法 (()=>{}) 定义匿名异步函数。通过在末尾添加 () 即可立即调用该函数。
await this.setGraphQL();:在匿名异步函数内部,它等待当前对象(this)上名为 setGraphQL() 的方法完成。此方法可能为服务器设置 GraphQL 功能。
this.setErrorHandler(app);:在匿名异步函数中,setGraphQL() 完成后,它会在当前对象(this)上调用名为 setErrorHandler() 的方法并传递一个 app 参数。此方法可能会为服务器设置一个错误处理程序。
第二种解决方案:
在第二个解决方案中,我修改了 notFoundHandler() 函数。
notFound.handler.js
module.exports = function notFoundHandler(app){
app.use((req,res,next)=>{
if(req.path == '/graphql'){
next();
}else{
res.status(404).json({
message: "Not Found Route"
})
}
})
}
notFoundHandler()中有一个if语句:if (req.path == '/graphql') { ... }。这将检查请求的路径是否等于“/graphql”。
如果 if 语句中的条件为 true,则调用 next() 函数。该函数用于将控制权传递给应用程序请求响应周期中的下一个中间件函数。
如果 if 语句中的条件为 false,则执行 else 块。
在 else 块中,res.status(404) 用于将 HTTP 响应状态代码设置为 404(未找到)。