在我經歷過的幾個以node為主的後端專案中,都有一個檔案 constant.js
。顧名思義,裡邊儲存著各種常量,而大多是字串與數字的對應關係。
但是在實際工作中,根據數字來除錯相當費勁,先不說後端程式碼中 where (status === 1)
這種可避免的神奇操作。(PS: 雖然我在吐槽它,但是有時我也會犯,給後來不熟悉業務者一臉懵逼...)。在資料庫中查詢也會遇到一些問題。
記得在我們資料庫中,有一個使用者表,其中一個欄位 user_type
中 1和2代表學生和老師,剛開始還可以輕易分清,後來文件對列的註釋給搞反了,自此每次查詢之前我都需要先查一遍資料庫的註釋,試想一下如果此時它是一個 enum('STUDENT', 'TEACHER') 的值,則可以輕易分清了,不需要再記各種數字了
以下以一個 TODO 的三種狀態 TODO
,DONE
以及 DOING
來描述下資料庫,後端和前端如何傳輸以及展示
本文地址 shanyue.tech/post/consta…
使用數字
在資料庫中使用數字來表示狀態,有可能是 Base 1 的 123,也有可能是 Base 0 的 012。不過最重要的是要記得在資料庫中對列新增註釋
-- mysql 可以直接註釋
create table todo (
status smallint default 1 comment "1: TODO, 2: DOING, 3: DONE";
)
-- postgres 在 comment 中進行註釋
create table todo (
status smallint default 1;
)
comment on column todo.status is '1: TODO, 2: DOING, 3: DONE';
複製程式碼
在後端為了篩選條件下避免以下情況的出現,需要維護一個 constant 的變數
const where = {
// 為了避免直接出現 1
Status: 1
}
複製程式碼
使用 Status 來維護一個常量,response 代表返給前端的資料
const Status = {
TODO: 1,
DOING: 2,
DONE: 3
}
const where = {
Status: Status.TODO
}
const response = [{
status: Status.TODO
}]
複製程式碼
在前端維護一個數字至中文展示的對映
const status_show = {
1: '待辦',
2: '進行中',
3: '已完成'
}
const url = '/api/todos?status=1'
複製程式碼
但在這種情況下,在進行介面聯調時仍會是 1/2/3,不便於除錯
使用 enum
在 postgres 中新增 todos_status 的 type
create type todo_status as enum ('UNDO', 'DOING', 'DONE');
create table todo (
status todo_status default 'UNDO',
);
複製程式碼
在後端可以直接在篩選條件中使用字串
const where = {
Status: 'TODO'
}
複製程式碼
如果為了避免使用字串打錯了字元,可以使用 typescript 的 const enum
在編譯器發現問題
const enum Status {
TODO = 'TODO',
DOING = 'DOING',
DONE = 'DONE'
}
const where = {
Status: Status.TODO
}
複製程式碼
編譯之後的 javascript 程式碼如下
var where = {
Status: "TODO" /* TODO */
};
複製程式碼
在前端維護一個常量至中文展示的對映,可以看出請求的 url 對於除錯與可讀性已經很友好了
const status_show = {
TODO: '待辦',
DOING: '進行中',
DONE: '已完成'
}
const url = '/api/todos?status=TODO'
複製程式碼
使用 graphql
資料庫依然使用 enum 來表示 TODO 的狀態
在 graphql 中,使用以下 Schema 表示 TODO,TodoStatus 以及查詢列表的 query。TodoStatus 可以使用 enum
來表示
enum TodoStatus {
DONE
DOING
UNDO
}
type Todo {
id: ID!
status: TodoStatus!
}
type Query {
todos (
status: TodoStatus
): [Poem!]
}
複製程式碼
使用以下 query 篩選 todos
query TODOS ($status: TodoStatus) {
todos (status: $status) {
id
status
}
}
複製程式碼