关于 MCV Service 的 Response 封装(装饰器)
案例技术栈
- 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 封装(装饰器)相关推荐
- python装饰器是什么意思_对Python装饰器的理解
想要弄明白装饰器是什么东西,首先我们需要了解一下什么是闭包,因为装饰器是闭包的一种应用. 闭包 闭包的定义: 通俗的来说闭包就是在一个函数内部定义另外一个函数,这个函数又引用了外部函数的变量,并且外 ...
- python response重头开始_你必须学写 Python 装饰器的五个理由
你必须学写Python装饰器的五个理由 ----装饰器能对你所写的代码产生极大的正面作用 作者:Aaron Maxwell,2016年5月5日 Python装饰器是很容易使用的.任何一个会写Pytho ...
- 面向对象特征:封装、多态 以及 @propetry装饰器
(继承补充)组合 obj=fun()#对象 obj.attr=foo()#对象的属性等于另一个对象 什么是组合: A类的对象具备某一个属性,该属性的值是B类的对象 基于这种方式就把 ...
- Python Day 21 面向对象 (面向对象的三大特性(二)继承,多态,封装,几个装饰器函数)...
Python Day 21 面向对象 (面向对象的三大特性(二)继承,多态,封装,几个装饰器函数) https://mubu.com/doc/1AqL_M0IbW 继承之钻石继承 多态 封装 几个装饰 ...
- 装饰器/使用类和对象封装一个工具类
# coding:utf-8 # 装饰器是以@开头,@结构称为语法糖,装饰器的作用主要是给现有的函数增加一些额外的功能. # @classmethod # @staticmethod # @prope ...
- Python学习日记(二十六) 封装和几个装饰器函数
封装 广义上的封装,它其实是一种面向对象的思想,它能够保护代码;狭义上的封装是面向对象三大特性之一,能把属性和方法都藏起来不让人看见 私有属性 私有属性表示方式即在一个属性名前加上两个双下划线 cla ...
- ant design pro 页面加载原理及过程,@connect 装饰器
一.概述 以列表页中的标准列表为主 Ant Design Pro 默认通过只需浏览器单方面就可处理的 HashHistory 来完成路由.如果要切换为 BrowserHistory,那在 src/in ...
- 一位Python初学者的自白:Python小白眼中的装饰器
这是在微信看到的一篇文章,伙伴刚学Python不久,我认真看了一下,确实是很真实的刚入门Python学习的伙伴!我把这篇文章拿到这来,也希望更多刚接触Python的伙伴能有所学,有所悟! 原文如下: ...
- 没看完这11 条,别说你精通 Python 装饰器
对于每一个学习 Python 的同学,想必对 @ 符号一定不陌生了,正如你所知, @ 符号是装饰器的语法糖,@符号后面的函数就是我们本文的主角:装饰器. 装饰器放在一个函数开始定义的地方,它就像一顶帽 ...
最新文章
- eve模拟器_EVE-NG,不仅仅是一款网络模拟软件,更是虚拟仿真环境
- python知识思维导图
- 关卡2-1 简单的模拟 1540 机器翻译
- Apollo自动驾驶入门课程第⑤讲 — 感知(下)
- Linux命令中正则表达式的运用
- OpenJudge NOI 1.6 07:有趣的跳跃
- raspberry pi_在Raspberry Pi上试用Docker
- a + b + c 求和
- python正则表达式提取字符串密码_用python正则表达式提取字符串
- Kaggle数据增强攻略来了!不氪金实现50种语言互译
- 深度学习TF—2.TensorFlow2高阶操作
- pandas——pd.DataFrame.iloc()
- iPhone6分辨率
- I2C 时序、速率计算及intel I2C驱动
- button3 电脑上mouse,鼠标侧键设置工具(X-Mouse Button Control)
- saltstack数据返回和模块定义
- 色彩缤纷的python(改变字体颜色及样式)不是我写的
- 【论文笔记_对比学习_2021】CONTRASTIVE LEARNING WITH HARD NEGATIVE SAMPLES
- halcon19.11深度学习关于分类入门案例
- WinDbg命令详解--执行
热门文章
- 【AUTOSAR】 S2S(Signal to Service) 信号转服务方案
- 【Mac版本】SourceTree无法push代码,提示Incorrect username or password
- jq制作樱花飘落特效
- 在Facebook iOS app中减少FOOMs
- ppp完全理解(一)
- 新超越极限地图和隐藏口令及装备合成公式
- mysql-5.7.16-winx64安装详解
- RedisJSON 横空出世!
- 如何将EML格式邮件导入notes数据库中
- 点菜系统源代码 php,点菜管理系统php源码 超级创新的一个 - 下载 - 搜珍网