案例技术栈

  • Nestjs
  • Typescript
  • mongoose

调试工具

  • Apifox

在过去的很长一段时间里我封装了很多Service返回值的标准输出格式,但冠绝都不够优雅,最开始使用带泛型的函数包裹返回值。现在我发现使用Decorator 来重新实现让编码更优雅,也更语义化。

// format.ts

/** @Descripttion: Format Service Response* @version: 0.0.0* @Author: Minyoung* @Date: 2022-03-27 21:09:58* @LastEditors: Minyoung* @LastEditTime: 2022-03-28 23:52:24*//*** 格式化列表查询返回结果* @param ...rest * @returns object { data, total, code, message }*/
export function ListResponse() {return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {const fn = descriptor.value;return {get() {return async (...rest) => {const { data: result, total } = await fn.call(this, ...rest);const data = result ? result : [];const code = result ? 200 : 201;const message = code === 200 ? 'success' : 'fail'return Promise.resolve({ data, total: total || 0, code, message });}}}}
}/*** 格式化单查询返回结果* @param rest * @returns object { data, code, message }*/
export function BasicResponse() {return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {const fn = descriptor.value;return {get() {return async (...rest) => {const { data } = await fn.call(this, ...rest);const code = data ? 200 : 201;const message = code === 200 ? 'success' : 'fail'return Promise.resolve({ data, code, message });}}}}
}/*** 格式化创建返回结果* @param rest * @returns object { result, code, message }*/export function CreateResponse() {return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {const fn = descriptor.value;return {get() {return async (...rest) => {const { result } = await fn.call(this, ...rest);const code = result ? 200 : 201;const message = code === 200 ? 'success' : 'fail'return Promise.resolve({ result, code, message });}}}}
}/*** 格式化更新返回结果* @param rest * @returns object { result, code, message }*/
export function UpdateResponse() {// {//   "acknowledged": true,//   "modifiedCount": 1,//   "upsertedId": null,//   "upsertedCount": 0,//   "matchedCount": 1// }return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {const fn = descriptor.value;return {get() {return async (...rest) => {const { result } = await fn.call(this, ...rest);const code = result.modifiedCount >= 1 ? 200 : 201;const message = code === 200 ? 'success' : 'fail'return Promise.resolve({ result, code, message });}}}}
}/*** 格式化删除返回结果* @param rest * @returns object { result, code, message }*/
export function DeleteResponse() {// {//   acknowledged: true,//   deletedCount: 0// }return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {const fn = descriptor.value;return {get() {return async (...rest) => {const { result } = await fn.call(this, ...rest);const code = result.deletedCount >= 1 ? 200 : 201;const message = code === 200 ? 'success' : 'fail'return Promise.resolve({ result, code, message });}}}}
}

应用于
// product.service.ts

/** @Descripttion: 产品 Serive* @version: 0.0.0* @Author: Minyoung* @Date: 2022-03-26 20:48:07* @LastEditors: Minyoung* @LastEditTime: 2022-03-28 23:51:50*/
import { Injectable } from '@nestjs/common';
import { CreateProductDto } from './dto/create-product.dto';
import { UpdateProductDto } from './dto/update-product.dto';
import { Product, ProductDocument } from './entities/product.entity';
import { Model } from 'mongoose';
import { InjectModel } from '@nestjs/mongoose';
import { ListResponse, BasicResponse, CreateResponse, UpdateResponse, DeleteResponse } from '../utils/format'@Injectable()
export class ProductsService {@InjectModel(Product.name) private readonly product: Model<ProductDocument>constructor() {}@CreateResponse()async create(createProductDto: CreateProductDto) {const result = await this.product.create(createProductDto);return { result };}@ListResponse()async findAll() {const data = await this.product.find().exec();const total = await this.product.countDocuments().exec();return { data, total };}@BasicResponse()async findOne(id: number) {const data = await this.product.findById(id).exec();return { data };}@UpdateResponse()async update(_id: string, updateProductDto: UpdateProductDto) {const result = await this.product.updateOne({ _id }, {$set: updateProductDto});return { result };}@DeleteResponse()async remove(_id: string) {const result = await this.product.deleteOne({ _id }).exec();return { result };}
}

调试结果示例:
列表返回[success]

{"data": [{"comments": [],"_id": "624034a87da67ec5435bb04a","title": "98年可乐","price": 198,"sale": 0,"timeLimit": 100,"banners": [],"createdAt": 1648374952937,"updatedAt": 1648471880892}],"total": 1,"code": 200,"message": "success"
}

删除返回[fail]

{"result": {"acknowledged": true,"deletedCount": 0},"code": 201,"message": "fail"
}

关于 MCV Service 的 Response 封装(装饰器)相关推荐

  1. python装饰器是什么意思_对Python装饰器的理解

    想要弄明白装饰器是什么东西,首先我们需要了解一下什么是闭包,因为装饰器是闭包的一种应用. 闭包 闭包的定义: ​通俗的来说闭包就是在一个函数内部定义另外一个函数,这个函数又引用了外部函数的变量,并且外 ...

  2. python response重头开始_你必须学写 Python 装饰器的五个理由

    你必须学写Python装饰器的五个理由 ----装饰器能对你所写的代码产生极大的正面作用 作者:Aaron Maxwell,2016年5月5日 Python装饰器是很容易使用的.任何一个会写Pytho ...

  3. 面向对象特征:封装、多态 以及 @propetry装饰器

    (继承补充)组合  obj=fun()#对象  obj.attr=foo()#对象的属性等于另一个对象  什么是组合:     A类的对象具备某一个属性,该属性的值是B类的对象    基于这种方式就把 ...

  4. Python Day 21 面向对象 (面向对象的三大特性(二)继承,多态,封装,几个装饰器函数)...

    Python Day 21 面向对象 (面向对象的三大特性(二)继承,多态,封装,几个装饰器函数) https://mubu.com/doc/1AqL_M0IbW 继承之钻石继承 多态 封装 几个装饰 ...

  5. 装饰器/使用类和对象封装一个工具类

    # coding:utf-8 # 装饰器是以@开头,@结构称为语法糖,装饰器的作用主要是给现有的函数增加一些额外的功能. # @classmethod # @staticmethod # @prope ...

  6. Python学习日记(二十六) 封装和几个装饰器函数

    封装 广义上的封装,它其实是一种面向对象的思想,它能够保护代码;狭义上的封装是面向对象三大特性之一,能把属性和方法都藏起来不让人看见 私有属性 私有属性表示方式即在一个属性名前加上两个双下划线 cla ...

  7. ant design pro 页面加载原理及过程,@connect 装饰器

    一.概述 以列表页中的标准列表为主 Ant Design Pro 默认通过只需浏览器单方面就可处理的 HashHistory 来完成路由.如果要切换为 BrowserHistory,那在 src/in ...

  8. 一位Python初学者的自白:Python小白眼中的装饰器

    这是在微信看到的一篇文章,伙伴刚学Python不久,我认真看了一下,确实是很真实的刚入门Python学习的伙伴!我把这篇文章拿到这来,也希望更多刚接触Python的伙伴能有所学,有所悟! 原文如下: ...

  9. 没看完这11 条,别说你精通 Python 装饰器

    对于每一个学习 Python 的同学,想必对 @ 符号一定不陌生了,正如你所知, @ 符号是装饰器的语法糖,@符号后面的函数就是我们本文的主角:装饰器. 装饰器放在一个函数开始定义的地方,它就像一顶帽 ...

最新文章

  1. eve模拟器_EVE-NG,不仅仅是一款网络模拟软件,更是虚拟仿真环境
  2. python知识思维导图
  3. 关卡2-1 简单的模拟 1540 机器翻译
  4. Apollo自动驾驶入门课程第⑤讲 — 感知(下)
  5. Linux命令中正则表达式的运用
  6. OpenJudge NOI 1.6 07:有趣的跳跃
  7. raspberry pi_在Raspberry Pi上试用Docker
  8. a + b + c 求和
  9. python正则表达式提取字符串密码_用python正则表达式提取字符串
  10. Kaggle数据增强攻略来了!不氪金实现50种语言互译
  11. 深度学习TF—2.TensorFlow2高阶操作
  12. pandas——pd.DataFrame.iloc()
  13. iPhone6分辨率
  14. I2C 时序、速率计算及intel I2C驱动
  15. button3 电脑上mouse,鼠标侧键设置工具(X-Mouse Button Control)
  16. saltstack数据返回和模块定义
  17. 色彩缤纷的python(改变字体颜色及样式)不是我写的
  18. 【论文笔记_对比学习_2021】CONTRASTIVE LEARNING WITH HARD NEGATIVE SAMPLES
  19. halcon19.11深度学习关于分类入门案例
  20. WinDbg命令详解--执行

热门文章

  1. 【AUTOSAR】 S2S(Signal to Service) 信号转服务方案
  2. 【Mac版本】SourceTree无法push代码,提示Incorrect username or password
  3. jq制作樱花飘落特效
  4. 在Facebook iOS app中减少FOOMs
  5. ppp完全理解(一)
  6. 新超越极限地图和隐藏口令及装备合成公式
  7. mysql-5.7.16-winx64安装详解
  8. RedisJSON 横空出世!
  9. 如何将EML格式邮件导入notes数据库中
  10. 点菜系统源代码 php,点菜管理系统php源码 超级创新的一个 - 下载 - 搜珍网