返回

紧跟社区前沿,koa+mongodb构建仿知乎接口(三)

见解分享

概览

构建一个社区接口涉及许多关键要素,其中包括用户关注和取消关注的功能。在本文中,我们将重点探讨如何使用koa和mongodb来实现这些功能。

1. 用户关注

1.1 路由

首先,我们需要定义路由来处理用户关注和取消关注的请求。在koa中,我们可以使用以下代码来定义路由:

// 关注用户
router.post('/follow/:userId', async (ctx) => {
  // 获取用户ID
  const userId = ctx.params.userId;

  // 获取当前登录用户ID
  const currentUserId = ctx.state.user._id;

  // 关注操作
  await followService.follow(currentUserId, userId);

  // 返回成功响应
  ctx.body = {
    success: true,
    message: '关注成功',
  };
});

// 取消关注用户
router.post('/unfollow/:userId', async (ctx) => {
  // 获取用户ID
  const userId = ctx.params.userId;

  // 获取当前登录用户ID
  const currentUserId = ctx.state.user._id;

  // 取消关注操作
  await followService.unfollow(currentUserId, userId);

  // 返回成功响应
  ctx.body = {
    success: true,
    message: '取消关注成功',
  };
});

1.2 服务层

在服务层,我们需要实现关注和取消关注的操作。这里我们使用一个名为followService的服务类来处理这些操作:

class FollowService {
  // 关注用户
  async follow(followerId, followedId) {
    // 更新关注者和被关注者的信息
    await Promise.all([
      UserModel.findByIdAndUpdate(followerId, {
        $addToSet: { following: followedId },
      }),
      UserModel.findByIdAndUpdate(followedId, {
        $addToSet: { followers: followerId },
      }),
    ]);
  }

  // 取消关注用户
  async unfollow(followerId, followedId) {
    // 更新关注者和被关注者的信息
    await Promise.all([
      UserModel.findByIdAndUpdate(followerId, {
        $pull: { following: followedId },
      }),
      UserModel.findByIdAndUpdate(followedId, {
        $pull: { followers: followerId },
      }),
    ]);
  }
}

1.3 数据模型

在数据模型中,我们需要定义用户模型来存储用户的信息,包括关注和粉丝列表:

const userSchema = new Schema({
  name: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true },
  following: [{ type: Schema.Types.ObjectId, ref: 'User' }],
  followers: [{ type: Schema.Types.ObjectId, ref: 'User' }],
});

2. 取消关注

取消关注的过程与关注类似,只需要在路由、服务层和数据模型中分别实现即可。

3. 正在关注列表

3.1 路由

为了获取当前登录用户的正在关注列表,我们需要定义一个新的路由:

// 获取正在关注列表
router.get('/following', async (ctx) => {
  // 获取当前登录用户ID
  const userId = ctx.state.user._id;

  // 获取正在关注列表
  const following = await followService.getFollowing(userId);

  // 返回成功响应
  ctx.body = {
    success: true,
    data: following,
  };
});

3.2 服务层

在服务层,我们需要实现获取正在关注列表的操作:

class FollowService {
  // 获取正在关注列表
  async getFollowing(userId) {
    // 查询用户关注列表
    const following = await UserModel.findById(userId).populate('following');

    // 返回关注列表
    return following.following;
  }
}

4. 粉丝列表

4.1 路由

为了获取当前登录用户的粉丝列表,我们需要定义一个新的路由:

// 获取粉丝列表
router.get('/followers', async (ctx) => {
  // 获取当前登录用户ID
  const userId = ctx.state.user._id;

  // 获取粉丝列表
  const followers = await followService.getFollowers(userId);

  // 返回成功响应
  ctx.body = {
    success: true,
    data: followers,
  };
});

4.2 服务层

在服务层,我们需要实现获取粉丝列表的操作:

class FollowService {
  // 获取粉丝列表
  async getFollowers(userId) {
    // 查询用户粉丝列表
    const followers = await UserModel.findById(userId).populate('followers');

    // 返回粉丝列表
    return followers.followers;
  }
}

5. 鉴权

为了确保只有登录用户才能执行关注和取消关注的操作,我们需要在路由中添加鉴权中间件:

router.use(async (ctx, next) => {
  // 获取请求头中的Authorization字段
  const authorization = ctx.request.headers.authorization;

  // 解析Authorization字段
  const token = authorization.split(' ')[1];

  // 验证token
  const user = await jwt.verify(token, secret);

  // 将用户对象挂载到ctx对象上
  ctx.state.user = user;

  // 继续执行下一个中间件或路由处理函数
  await next();
});

总结

通过koa和mongodb,我们可以轻松实现类似知乎的社区接口中的用户关注和取消关注功能。本文提供了详细的代码示例,帮助读者快速上手。