GraphQL 全栈开发示例
GraphQL 是一种用于 API 的查询语言,它提供了一种更高效、强大和灵活的方式来获取数据。在本文中,我们将演示如何使用 GraphQL 进行全栈开发,并展示一个示例应用程序。
技术栈
- 前端: React、Apollo Client
- 后端: Node.js、Express、Apollo Server、MongoDB
功能需求
我们将创建一个简单的文章应用程序,用户可以发布文章并进行评论。具体功能包括:
- 用户注册/登录
- 发布文章
- 编辑/删除文章
- 查看所有文章列表
- 查看单个文章及其评论
- 对文章进行评论
数据模型
我们首先定义我们的数据模型。在 MongoDB 中,我们将有两个集合:User 和 Article。User 集合将用于存储用户数据,Article 集合将用于存储文章和评论数据。以下是我们的数据模型:
javascript
复制代码
const userSchema = new mongoose.Schema({
username: String,
password: String,
});
const articleSchema = new mongoose.Schema({
title: String,
content: String,
author: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true,
},
comments: [{
content: String,
author: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true,
},
}],
});
后端实现
现在我们开始建立后端。我们将使用 Node.js 和 Express 来创建服务器,使用 Apollo Server 搭建 GraphQL API 服务。
安装依赖
首先,我们需要安装以下依赖:
express
apollo-server-express
mongoose
bcryptjs
jsonwebtoken
其中,bcryptjs
用于密码加密,jsonwebtoken
用于用户认证和授权。
bash
复制代码
npm install express apollo-server-express mongoose bcryptjs jsonwebtoken --save
配置数据库连接
接下来,我们配置 MongoDB 的连接。在项目根目录下新建一个 config.js
文件,并添加以下代码:
javascript
复制代码
module.exports = {
dbUrl: 'mongodb://localhost/graphql-example',
jwtSecret: 'my-secret-key',
};
其中,dbUrl
是 MongoDB 的连接 URL,jwtSecret
是用于签发 JWT token 的秘钥。
然后,我们在项目的入口文件 index.js
中引入该配置文件,并连接 MongoDB:
javascript
复制代码
const { ApolloServer } = require('apollo-server-express');
const express = require('express');
const mongoose = require('mongoose');
const config = require('./config');
const typeDefs = require('./typeDefs');
const resolvers = require('./resolvers');
const app = express();
// 连接 MongoDB 数据库
mongoose.connect(config.dbUrl, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => console.log('MongoDB Connected'))
.catch(err => console.log(err));
// 创建 ApolloServer 实例
const server = new ApolloServer({
typeDefs,
resolvers,
context: ({ req }) => {
// 在 context 中解析 JWT token 并将当前登录用户存储在上下文中
const token = req.headers.authorization || '';
if (token) {
try {
const user = jwt.verify(token, config.jwtSecret);
return { user };
} catch (err) {
console.log(err);
}
}
return {};
},
});
server.applyMiddleware({ app });
const port = process.env.PORT || 4000;
app.listen(port, () =>
console.log(`Server running at http://localhost:${port}${server.graphqlPath}`)
);
定义用户模型和相关操作
接着,我们定义用户模型和相关操作。在一个新的 models/user.js
文件中添加以下代码:
javascript
复制代码
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const userSchema = new mongoose.Schema({
username: String,
password: String,
});
userSchema.pre('save', async function() {
if (!this.isModified('password')) {
return;
}
this.password = await bcrypt.hash(this.password, 10);
});
userSchema.methods.comparePassword = async function(password)
GraphQL 全栈开发示例
GraphQL 是一种用于 API 的查询语言,它提供了一种更高效、强大和灵活的方式来获取数据。在本文中,我们将演示如何使用 GraphQL 进行全栈开发,并展示一个示例应用程序。
技术栈
- 前端: React、Apollo Client
- 后端: Node.js、Express、Apollo Server、MongoDB
功能需求
我们将创建一个简单的文章应用程序,用户可以发布文章并进行评论。具体功能包括:
- 用户注册/登录
- 发布文章
- 编辑/删除文章
- 查看所有文章列表
- 查看单个文章及其评论
- 对文章进行评论
数据模型
我们首先定义我们的数据模型。在 MongoDB 中,我们将有两个集合:User 和 Article。User 集合将用于存储用户数据,Article 集合将用于存储文章和评论数据。以下是我们的数据模型:
javascript
复制代码
const userSchema = new mongoose.Schema({
username: String,
password: String,
});
const articleSchema = new mongoose.Schema({
title: String,
content: String,
author: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true,
},
comments: [{
content: String,
author: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true,
},
}],
});
后端实现
现在我们开始建立后端。我们将使用 Node.js 和 Express 来创建服务器,使用 Apollo Server 搭建 GraphQL API 服务。
安装依赖
首先,我们需要安装以下依赖:
express
apollo-server-express
mongoose
bcryptjs
jsonwebtoken
其中,bcryptjs
用于密码加密,jsonwebtoken
用于用户认证和授权。
bash
复制代码
npm install express apollo-server-express mongoose bcryptjs jsonwebtoken --save
配置数据库连接
接下来,我们配置 MongoDB 的连接。在项目根目录下新建一个 config.js
文件,并添加以下代码:
javascript
复制代码
module.exports = {
dbUrl: 'mongodb://localhost/graphql-example',
jwtSecret: 'my-secret-key',
};
其中,dbUrl
是 MongoDB 的连接 URL,jwtSecret
是用于签发 JWT token 的秘钥。
然后,我们在项目的入口文件 index.js
中引入该配置文件,并连接 MongoDB:
javascript
复制代码
const { ApolloServer } = require('apollo-server-express');
const express = require('express');
const mongoose = require('mongoose');
const config = require('./config');
const typeDefs = require('./typeDefs');
const resolvers = require('./resolvers');
const app = express();
// 连接 MongoDB 数据库
mongoose.connect(config.dbUrl, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => console.log('MongoDB Connected'))
.catch(err => console.log(err));
// 创建 ApolloServer 实例
const server = new ApolloServer({
typeDefs,
resolvers,
context: ({ req }) => {
// 在 context 中解析 JWT token 并将当前登录用户存储在上下文中
const token = req.headers.authorization || '';
if (token) {
try {
const user = jwt.verify(token, config.jwtSecret);
return { user };
} catch (err) {
console.log(err);
}
}
return {};
},
});
server.applyMiddleware({ app });
const port = process.env.PORT || 4000;
app.listen(port, () =>
console.log(`Server running at http://localhost:${port}${server.graphqlPath}`)
);
定义用户模型和相关操作
接着,我们定义用户模型和相关操作。在一个新的 models/user.js
文件中添加以下代码:
javascript
复制代码
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const userSchema = new mongoose.Schema({
username: String,
password: String,
});
userSchema.pre('save', async function() {
if (!this.isModified('password')) {
return;
}
this.password = await bcrypt.hash(this.password, 10);
});
userSchema.methods.comparePassword = async function(password)