除規(guī)范定義的標(biāo)量外幔摸,還可以按需定義業(yè)務(wù)范疇內(nèi)的標(biāo)量摸柄。語法非常簡單
本文是基于node實現(xiàn)的服務(wù)定義
scalar Datetime
注意,這只是語義范疇定義既忆,還需要定義序列化驱负、反序列化函數(shù):
new GraphQLScalarType({
name: "Datetime",
description: "日期時間標(biāo)量類型",
// 序列化函數(shù)
serialize(value) {
return value.toString();
},
// 解析函數(shù)
parseValue(value) {
if (typeof value === "string") {
return new Date(value);
}
throw new Error("參數(shù)類型錯誤");
},
// 解析函數(shù)
parseLiteral(ast) {
if (ast.kind === Kind.STRING) {
return new Date(ast.value);
}
throw new Error("參數(shù)類型錯誤");
}
});
關(guān)于graphQL標(biāo)量類型定義詳細內(nèi)容參考官方文檔
下面我們一個一個看這些配置:
- name: 字段名,請保持與schema中定的標(biāo)量類型名稱保持一致
- description: 類型描述尿贫,在一些診斷工具上還是很有用的
- serialize: 序列化函數(shù)电媳,用于將結(jié)果轉(zhuǎn)換為適合 http 傳輸?shù)臄?shù)值類型
- parseValue: 解析函數(shù),用于將客戶端通過 variables 參數(shù)傳遞的數(shù)值為 Date 類型
- parseLiteral: 同樣是解析函數(shù)庆亡,將客戶端傳遞的字面量參數(shù)解析為 Date 類型
配置中的 parseValue匾乓、parseLiteral 兩個函數(shù)功能上相似,都用于解析客戶端參數(shù)又谋,分別處理兩種參數(shù)傳遞方式:
# 1. variables 參數(shù)
# 引擎將調(diào)用 parseValue 函數(shù)
query (before: Datetime){
users(before: $before) {
id
name
}
}
variables {
before: "1991-02-19"
}
# 2. 字面量參數(shù)
# 引擎將調(diào)用 parseLiteral 函數(shù)
query {
users(before: "1991-02-19") {
id
name
}
}
最后說一些注意點:
- 如果類型確定不會作為 InputType拼缝,可以省略 parseValue、parseLiteral
- parseValue 接收到的是 variables 對象中對應(yīng)的值彰亥;而 parseLiteral 接收的則是引擎從 query 語句中解析出的 AST 節(jié)點咧七。AST 節(jié)點內(nèi)容形如:
{
// 字面量類型
"kind": "StringValue",
// 字面量值
"value": "1991-02-19",
// 指明字面量是否為 [BlockStringValue](https://facebook.github.io/graphql/June2018/#BlockStringValue()) 類型
"block": false,
// token 位置
"loc":
{
"start": 18,
"end": 30
}
}
在定義具體數(shù)據(jù)類型的時候可以使用這個新類型:
type Comment {
id: Int!
content: String
feedbackId: Int
gmtCreate: Datetime
gmtModified: Datetime
}
返回對象的標(biāo)量
標(biāo)量類型也支持返回結(jié)構(gòu)化的對象,只要能為引擎提供符合規(guī)則的 serialize 函數(shù)任斋,一切皆有可能继阻。我們可以寫出這樣一個標(biāo)量:
// Address 對象類型,不過這是一個標(biāo)量
new GraphQLScalarType({
name: "Address",
description: "對象類型的標(biāo)量",
serialize(value) {
// value 為對象類型
// value = { city: '深圳', province: '廣東省', country: '中國' }
return value;
}
});
但是要注意废酷,標(biāo)量類型是 不可分割 的瘟檩,不能再傳入查詢子集:
# 合法請求
query {
users {
id
name
# Address 類型值
bornOrigin
}
}
返回結(jié)果:
{
"data": {
"users": [
{
"id": "1",
"name": "foo",
"bornOrigin": {
"city": "深圳",
"province": "廣東省",
"country": "中國"
}
}
]
}
}
總結(jié)
標(biāo)量是 GraphQL 中的原子類型,一般充當(dāng)查詢的葉子節(jié)點澈蟆。 GraphQL 規(guī)范提供了五種標(biāo)量類型墨辛,其中 ID 最為特殊,用于唯一標(biāo)志一個資源實例趴俘。 在標(biāo)準(zhǔn)標(biāo)量之外睹簇,也可以按需定義新的標(biāo)量,規(guī)則如上寥闪。