一、环境准备
1. Node.js环境安装
bash# 安装Node版本管理器
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
# 安装Node.js LTS版本
nvm install --lts
nvm use --lts
# 验证安装
node --version
npm --version
2. 项目初始化
bash# 创建项目目录
mkdir graphql-server
cd graphql-server
# 初始化项目
npm init -y
# 安装依赖
npm install apollo-server graphql mongoose express
二、GraphQL服务器搭建
1. 基础服务器配置
javascript// index.js
const { ApolloServer } = require('apollo-server');
const typeDefs = require('./schema');
const resolvers = require('./resolvers');
const server = new ApolloServer({
typeDefs,
resolvers,
context: ({ req }) => ({
token: req.headers.authorization
}),
formatError: (error) => {
console.error(error);
return error;
}
});
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
2. Schema定义
javascript// schema.js
const { gql } = require('apollo-server');
const typeDefs = gql`
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
content: String!
author: User!
}
type Query {
users: [User!]!
user(id: ID!): User
posts: [Post!]!
post(id: ID!): Post
}
type Mutation {
createUser(name: String!, email: String!): User!
createPost(title: String!, content: String!, authorId: ID!): Post!
}
`;
module.exports = typeDefs;
三、数据库集成
1. MongoDB连接配置
javascript// db.js
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/graphql', {
useNewUrlParser: true,
useUnifiedTopology: true
});
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
db.once('open', () => console.log('Connected to MongoDB'));
2. 模型定义
javascript// models/User.js
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
name: String,
email: String,
posts: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Post' }]
});
module.exports = mongoose.model('User', userSchema);
四、解析器实现
1. Query解析器
javascript// resolvers/queries.js
const queries = {
users: async (_, __, { dataSources }) => {
return await dataSources.users.getAll();
},
user: async (_, { id }, { dataSources }) => {
return await dataSources.users.findById(id);
},
posts: async (_, __, { dataSources }) => {
return await dataSources.posts.getAll();
}
};
2. Mutation解析器
javascript// resolvers/mutations.js
const mutations = {
createUser: async (_, { name, email }, { dataSources }) => {
return await dataSources.users.create({ name, email });
},
createPost: async (_, { title, content, authorId }, { dataSources }) => {
return await dataSources.posts.create({
title,
content,
authorId
});
}
};
五、性能优化
1. 数据加载优化
javascript// dataloaders/user.js
const DataLoader = require('dataloader');
const User = require('../models/User');
const batchUsers = async (ids) => {
const users = await User.find({ _id: { $in: ids } });
return ids.map(id => users.find(user => user.id === id));
};
module.exports = new DataLoader(batchUsers);
2. 查询优化
javascriptCopy// 实现字段级缓存
const resolvers = {
User: {
posts: {
resolve: async (user, _, { loaders }) => {
return await loaders.postsByUser.load(user.id);
},
cacheControl: {
maxAge: 60
}
}
}
};
六、安全配置
1. 认证中间件
javascript// middleware/auth.js
const jwt = require('jsonwebtoken');
const authenticate = async (req) => {
const token = req.headers.authorization;
if (!token) return null;
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
return decoded.user;
} catch (err) {
return null;
}
};
module.exports = authenticate;
2. 请求限制
javascriptconst { ApolloServer } = require('apollo-server-express');
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15分钟
max: 100 // 限制100次请求
});
app.use('/graphql', limiter);
七、部署配置
1. PM2部署配置
javascript// ecosystem.config.js
module.exports = {
apps: [{
name: 'graphql-server',
script: './index.js',
instances: 'max',
autorestart: true,
watch: false,
max_memory_restart: '1G',
env: {
NODE_ENV: 'production'
}
}]
};
2. Nginx反向代理
nginxserver {
listen 80;
server_name api.yourdomain.com;
location /graphql {
proxy_pass http://localhost:4000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
最佳实践建议
- 开发规范
- 使用TypeScript提升代码质量
- 实现错误处理机制
- 添加适当的日志记录
- 性能优化
- 使用数据加载器减少查询
- 实现适当的缓存策略
- 优化查询复杂度
- 安全考虑
- 实施适当的认证授权
- 限制查询深度和复杂度
- 防范常见的GraphQL攻击
本指南为您提供了在云服务器上部署GraphQL服务的完整方案。记住,一个好的GraphQL服务不仅需要正确的配置,还需要合理的架构设计和持续的优化维护。建议在正式部署前进行充分的测试和性能评估。
同时,要注意保持依赖包的更新,关注安全公告,及时修复潜在的安全漏洞。对于生产环境的GraphQL服务,建议建立完善的监控系统,确保服务的稳定运行。