關于默認值、唯一性約束和 API 設計,我有一個最佳實踐問題。對于這個練習,我在 postgresql 中使用以下資料庫模式創建一個 pokedex api。
create_table :pokemon, id: :uuid do |t|
t.string :name, null: false, unique: true
t.string :national_index, null: false, unique: true
t.text :description, default: 'unknown', null: false
t.string :hp, default: '0', null: false
t.string :attack, default: '0', null: false
t.string :defense, default: '0', null: false
t.string :special_attack, default: '0', null: false
t.string :special_defense, default: '0', null: false
t.string :speed, default: '0', null: false
t.string :height, default: '0', null: false
t.string :weight, default: '0', null: false
t.boolean :male, default: false, null: false
t.boolean :female, default: false, null: false
t.string :category, default: 'unknown', null: false
t.timestamps
end
正如您從這個 rails 遷移中看到的那樣,我對所有欄位都有存在約束,并為 pokemon 的名稱及其國家索引添加了唯一約束。此外,您可以在資料庫遷移中看到,如果無法確定口袋妖怪的戰斗統計并且其描述和類別屬于“未知”作為其默認值,則口袋妖怪的戰斗統計以默認值 0 表示。
這是我的情況,我認為最好用用戶用例來解釋。
假設一個口袋妖怪研究人員遇到了一個新的未被發現的口袋妖怪,并通過我正在創建的 api 將該口袋妖怪上傳到 pokedex 資料庫。我想在這種情況下,口袋妖怪研究人員將不得不給這個口袋妖怪一個名字(以后可以更改),并且這個口袋妖怪的其余欄位將全部填充默認值,一旦進行更多研究,這些值也可以在以后更改在口袋妖怪上。但是,口袋妖怪研究人員無法為其分配國家索引號,因為它是“未知”的口袋妖怪。只有官方認可的口袋妖怪才能擁有國家索引編號,并且沒有兩個官方或未被發現的口袋妖怪可以有沖突的編號。換句話說,它沒有得到官方認可。所以我的問題,我可以使用什么來向我定義為存在且唯一的欄位添加默認值?我很想給它一個N/A, unkown, 或其他型別的值,但我不能,因為它們不是唯一的。下一個未被發現的 pokemon 的國家索引號也不能具有“N/A”值。對于這種情況,是否有最佳做法?
您可能會爭辯說,也許最好將這些欄位留空,但在我正在閱讀的這本關于 API 設計的優秀書籍中,我專門在字串的默認值下參考了本節。
類似地,對于數字和布爾欄位,許多序列化格式不一定允許與零值 ("") 不同的空值 (null)。因此,很難確定用戶指定字串應為空字串與用戶具體要求 API 為給定其余背景關系的欄位“做最好的事情”之間的區別。
幸運的是,有很多可用的選項。在許多情況下,空字串根本不是欄位的有效值。結果,空字串確實可以用作指示應該注入和保存默認值的標志。在其他情況下,字串值可能具有一組特定的適當值,其中空字串是選項之一。在這種情況下,允許選擇“默認”作為指示應該存盤默認值的標志是完全合理的。
這本書似乎提倡默認值,但在我描述的情況下甚至可能嗎?基本上,我希望我的 api 是可預測和可靠的,并且我想象我描述的場景是經常發生的事情。
uj5u.com熱心網友回復:
您可以在應用程式級別為更復雜的場景設定默認值
class Pokemon < ActiveRecord::Base
before_validation :set_national_index, on: :create
private
def set_national_index
self.national_index = if official?
# ...
else
"unknown_#{Time.zone.now.to_i}_#{rand(99999)}"
end
end
end
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/488171.html
上一篇:擴展類中未定義箭頭函式
