前文
今天公司有人不怎么会nestjs
部长让我教一下
突然他问了我一个发自灵魂的问题
DTO是什么?
我一脸懵逼,随即转为愤怒
当时就给他一脚
就你事多
(开玩笑
但是仔细搜了一下确实没什么关于DTO的文章和解释
于是我参考了一些国外的资料
大概理解了为什么需要DTO
由于也是第一次研究
可能存在事实错误
欢迎评论里指出
并且不同语言对DTO的实现也不尽相同
本文提到的不一定在某一个语言/框架的DTO实现
正文
我们先假设现在是1970年
存在一个客户端,一个服务器
Client-》Server
我们开发好了API
开发好了后
发现一个巨大的问题
用户除了提交我们所需的数据后
还可以附加其他的数据,很容易被猜测字段形成越权攻击,而且存在多余数据
那我们就有一个需求
我们能不能只获取我们需要的数据?
那思路很简单
我们后端API提取我们所需的数据,然后再生成类
形成一个
const id=data.id
const name=data.name
new Person(id,name)
那问题来了
我们想在一百处API用这段提取代码
该怎么办?
设计也非常简单,我们把上述代码抽解成一个函数
在api路由里调用这个函数就可以
function handleData(data){
const id=data.id
const name=data.name
return {id,name}
}
那又来了一个问题,假设我们提取不同的数据模式,我们该怎么处理?
可以给这个函数传入一个对象,根据这个对象从api数据中提取我们所需的数据
因为这个函数在大部分框架开发中都可以使用到
所以干脆将这个函数挪到框架
我们只需要声明一个对象
就可以实现数据的提取
DTO的拓展
除了数据的提取,其实也可以用于服务器返回的数据的精简
如我们从sql获取了id,name,card,我们只想返回id,name
同样可以声明DTO来限制返回的数据
这样我们就实现了提交数据的过滤,返回数据的过滤
Client-》DTO-》Server-》DTO-》Client
基于这个基础
还有很多拓展的功能
如对属性进行长度的最大最小限制
对返回的属性的一些值进行自动计算等
DTO的转换
通常来说DTO是一个纯的对象,没有任何操作,有一些实现会提供序列化和反序列化
假设我们一个API需要两个数据,一个Person标识身份,一个Work标识工作
function generatorMessage(data:{Person,Work}){
xxxx
}
这个时候我们提交给这个API数据的时候
书写了DTO可以自动精简Person不存在的属性然后发送,减少了网络损耗
同时对方接受了DTO后
已经做好属性的校验和精简等
可以直接基于DTO进行类的创建和数据的存储
以防利用多余字段攻击及更方便的创建类
大大提高了开发效率
结语
撒花~