上一篇提到使用管道來驗證資料,在傳送資料進入到控制器之前,先驗證資料是否正確,以前做無謂的功或者避免因為缺少資料讓後面的流程爆炸。
管道除了用來驗證資料以外,也可以用來轉換資料。
管道在轉換的時候,可以完全覆蓋原本傳送過來的值。就可以想像到一種使用情境:例如從客戶端傳送過來的參數,可能不甚準確、或有遺漏,導致無法使用參數獲得想要的結果。為了不讓參數變得毫無作用,可以使用管道將參數轉換成合法且可以使用的型態,填補了客戶端和伺服器端之間的空白
本次要來建立一個轉換整數的管道,名為:parseInt
nest generate pipe parseInt
export class ParseIntPipe implements PipeTransform<string> {
async transform(value: string, metadata: ArgumentMetadata) {
const val = parseInt(value, 10);
if (isNaN(val)) {
throw new BadRequestException('Validation failed');
}
return val;
}
}
這是一個很簡單的轉換,將輸入的值轉換,使用 parseInt
的方法。將輸入的內容轉換成十進位的整數,如果輸入的內容不能轉換成十進位的整數,就拋出錯誤
修改取得指定文件編號的方法
@Get('/:id')
getDocument(@Param('id', new ParseIntPipe()) id, @Response() res) {
this.documentService.getDocumentData().subscribe(data => {
let resData = data.filter(data => data.id === id)
res.status(HttpStatus.OK).json(resData);
})
}
其中修改的部分
@Param('id', new ParseIntPipe()) id
這一段的意思是,取得參數id,也就是取得特定文件的編號。並且使用管道- ParseIntPipe轉換資料,而且給予這個參數名稱同樣叫作id
如此一來,當getDocument方法啟動取得參數之前,就會先被管道轉換成我們要的資料,而不再是從客戶端直接傳送過來的資料。
最明顯的證據可以看到這一行
let resData = data.filter(data => data.id === id)
還記得在控制器的篇章怎麼寫的嗎?
let resData = data.filter(data => data.id === Number(param.id))
因為從客戶端傳過來的參數一定會被轉換成字串,所以要在控制器自行轉成數字的型態才能比較。
使用管道轉換資料之後,因為管道已經幫我們轉換成數字,所以不必再轉換成數字,可以直接使用
使用postman測試
以下使用三組參數來測試
前兩組的測試結果應該要正確顯示萊布尼茲的單子論,最後一組的結果應該出現錯誤
參數輸入2.000
參數輸入2.14159
參數輸入aaa
有時候客戶端和伺服器端的溝通總會出現許多不明意外的錯誤,例如明明要傳1,傳過來會變成1.00,這樣導致花了很多時間除錯,所以為了避免這種意外,理論上客戶端和伺服器端都要有這種防錯的措施,就可以避免很多這種非預期的意外
(對! IE我就是說你,有時候頁面送出整數偏偏要給我偷加成小數)
今天的範例內容可以github上面看到:範例內容
今天學到的事情有: