使用koa+mongodb构建的仿知乎接口(二)

1. 实现图片上传接口

需求:知乎中用户编辑资料的图片上传

分析:通过把图片上传到服务器中,再返回url

  1. 因为要识别file类型的参数,所以需要使用koa-body,koa-bodyparser无法识别。
const KoaBody = require('koa-body')app.use(KoaBody({ multipart: true, formidable: { // 设置上传地址 uploadDir: path.join(__dirname, '/public/uploads'), // 保留图片后缀 keepExtensions: true }}))
  1. 要把url返回,需要使用koa-static管理静态资源
const KoaStatic = require('koa-static')app.use(KoaStatic( path.join(__dirname, staticPath)))
  1. 注册上传图片路由
router.post('/upload', upload)
  1. 实现上传的控制器函数
// home.jsupload (ctx) { const file = ctx.request.files.file const basename = path.basename(file.path) ctx.body = { url: `${ctx.origin}/uploads/${basename}` }}
  1. 使用Postman测试

2. 实现用户资料编辑接口

需求:如图所示,实现编辑用户资料的接口

  1. 重新设计用户的Schema,较之前,增加一些字段
const UserSchema = new Schema({ ... avatar_url: {type: String}, gender: {type: String, enum: ['male', 'female'], default: 'male'}, headline: {type: String}, locations: {type: [{type: String}], select: false}, business: {type: String, select: false}, employments: { type: [{ company: {type: String}, job: {type: String}, }], select: false }, educations: { type: [{ school: {type: String}, major: {type: String}, diploma: {type: Number, enum: [1, 2, 3, 4, 5]}, enterance_year: {type: Number}, graduation_year: {type: Number} }], select: false }, following: { type: [{type: Schema.Types.ObjectId, ref: 'User'}], select: false }})
  1. 修改users控制器中的update方法
async update(ctx) { ctx.verifyParams({ name: {type: 'string', required: false}, password: {type: 'string', required: false}, avatar_url: {type: 'string', required: false}, gender: {type: 'string', required: false}, headline: {type: 'string', required: false}, locations: {type: 'array', itemType: 'string', required: false}, business: {type: 'string', required: false}, employments: {type: 'array', itemType: 'object', required: false}, educations: {type: 'array', itemType: 'object', required: false}, }) const user = await User.findByIdAndUpdate(ctx.params.id, ctx.request.body) if (!user) {ctx.throw(404, '用户不存在')} ctx.body = user}
  1. 修改users控制器中的findById方法,实现过滤字段
async findById(ctx) { const {fields} = ctx.query const selectFields = fields.split(';').filter(f => f).map(f => ' +' + f).join('') const user = await User.findById(ctx.params.id).select(selectFields) if (!user) {ctx.throw(404, '用户不存在')} ctx.body = user}
  1. 使用Postman测试

总结:

  1. 写接口的步骤一般是:
  • a. 定义数据模型Schema

  • b. 编写转发的路由

  • c. 使用数据模型编写控制器逻辑

  • e. 使用Postman测试

  • f. 编写单元测试和压测

2.更新或者删除用户的信息,是需要鉴权的过程的。

相关文章