• 使用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.js
    upload (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.更新或者删除用户的信息,是需要鉴权的过程的。

  • 相关阅读:
    tsc errors All In One
    TypeScript declare Set Array type All In One
    Linux exit nano editor All In One
    Linux bash pbcopy command All In One
    千焦与千卡的换算公式 All In One
    linux 中 sed N选项将两行合并为一行处理
    linux 中 sed n选项将两行作为一行处理,屏蔽第一行
    linux 中sed命令删除匹配字符之前的一行
    linux 中sed命令 P和p的区别
    linux 中 sed命令替换命令时i选项忽略大小写
  • 原文地址:https://www.cnblogs.com/Jomsou/p/12500180.html
Copyright © 2020-2023  润新知