iT邦幫忙

2024 iThome 鐵人賽

DAY 20
0
Modern Web

一些讓你看來很強的 ORM - prisma系列 第 20

Day20. 一些讓你看來很強的 ORM - prisma (Omit Fields )

  • 分享至 

  • xImage
  •  

今天的主題要來介紹 omit fields ,我們可能會有一個情況是,不希望 DB 的欄位被別人看到,我們希望只 return 需要用到的欄位就好,確保隱密的欄位不會被看到,常見的例子例如 userpassword ,我們當然不希望當我們在拿 user list 的時候,同時也把所有 userpassword 都暴露出來,這樣是非常可怕的事情,那為了阻止這種事情發生,我們就來學一下 prisma 如何去 omit fields 吧~

Demo

今天我們就拿 user 隱藏 password 來示範,以下是 User model

model User {
  id       String @id @default(cuid())
  name     String
  email    String @unique
  password String
}

那要使用 omit 這個功能,必須開啟 previewFeatures.omitApi 這個 feature 才能使用喔~

generator client {
  provider = "prisma-client-js"
  previewFeatures = ["omitApi"]
}

然後每次添加新的 previewFeatures 都要記得 generate previewFeatures才能生效

>npx prisma generate  

在還沒 omit 之前當我們 query user 的時候就會按照 model 的欄位去 return 所有的 fields ,同時你也可以看到有哪些 fields type

const user = await prismaClient.user.findFirst()

https://ithelp.ithome.com.tw/upload/images/20241006/20145677JKjzcrog5E.png

{
  id: 'cm1uuaqmo0000egova98vq5k6',
  name: 'danny',
  email: 'hiunji64@gmail.com',
  password: 'fsdfgdfsgdfgfd'
}

那要 omit password 很簡單,我們只需要在 findFirst 加上 omit 就好

 const user = await prismaClient.user.findFirst({
      omit: {
        password: true
      }
    })

然後很神奇的是,你 omit 完的 result 他的 type 也會自動幫你 omit

https://ithelp.ithome.com.tw/upload/images/20241006/20145677sKz4X7FpeO.png

然後 response 的結果就不會包含 password

{
  id: 'cm1uuaqmo0000egova98vq5k6',
  name: 'danny',
  email: 'hiunji64@gmail.com'
}

但這時我們可能思考到一種情況,如果我們 get User 的地方越多,那我們是不是每次都要加上 omit 這個欄位,這部分 prisma 很貼心的提供 global omit 的方式,讓你一次就 omit ,你只需要在 PrismaClient 中告訴哪些 model 的哪些欄位要 omit

const prismaClient = new PrismaClient({
  omit: {
    user: {
      password: true
    }
  }
})

如此就算我們在 local 沒有加上 omitresponse 也會 omitpassword

const user = await prismaClient.user.findFirst()
{
  id: 'cm1uuaqmo0000egova98vq5k6',
  name: 'danny',
  email: 'hiunji64@gmail.com'
}

那假如我們定好 global omit 後,想要在特定的地方看到 userpassword 的話只要加上 select 就可以了

const user = await prismaClient.user.findFirst({
      select: {
        id: true,
        password: true
      }
    })
{ id: 'cm1uuaqmo0000egova98vq5k6', password: 'fsdfgdfsgdfgfd' }

或者另外一種方式把 omit 改成 false

const user = await prismaClient.user.findFirst({
      omit: {
        password: false
      }
    })

一樣都可以看到 password 這個欄位,就看你習慣什麼寫法~

{
  id: 'cm1uuaqmo0000egova98vq5k6',
  name: 'danny',
  email: 'hiunji64@gmail.com',
  password: 'fsdfgdfsgdfgfd'
}

When To Use Omit

以上就是今天提到的 global omitlocal omit 寫法,那至於什麼情況該用什麼 omit 這邊簡單比較一下兩著的差異與使用情況~

安全性方面

如果您擔心安全性或暴露敏感訊息,最好使用 global omit 。這樣可以確保新編寫的查詢不會無意中包含敏感資料。在大多數情況下,您應該優先選擇這種方法,一個很好的用例是始終省略使用者密碼

效能方面

如果您更關注資料傳輸量和效能,可以考慮使用 local omit。這允許您在大多數查詢中繼續使用模型的所有字段,然後在資料傳輸量較大的情況下進行最佳化。

例如,如果您有一個表,其中每個列的資料都比較輕量,但有一列包含大量JSON或Blob數據,您可以輕鬆地排除該列,以避免每次請求都需要傳輸所有資料。

總結

  • 使用 global omit 以確保安全性和隱私。
  • 使用 local omit 以優化資料傳輸和效能。
  • 根據您的特定需求選擇合適的方法。
  • 可以結合使用兩種方法,例如在大多數查詢中使用 global omit ,但在特定情況下再次包含被省略的欄位。

大家如果有問題可以來小弟的群組討論~

✅ 前端社群 :
https://lihi3.cc/kBe0Y


上一篇
Day19. 一些讓你看來很強的 ORM - prisma (customer methods)
下一篇
Day21. 一些讓你看來很強的 ORM - prisma ( Seed Data)
系列文
一些讓你看來很強的 ORM - prisma30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言