GraphQL 第二章 Schema 和類型

GraphQL 第二章 Schema 和類型

定義了 schema 後我們就能知道服務器會返回那種對象,這些對象有哪些字段可用等。
每個 GraphQL 服務都會定義一套類型,用以描述你可能從那個服務查詢到的數據,每當查詢到來,服務器就會根據 schema 驗證並執行查詢。
之前我們講了 GraphQL 的查詢語言,這裏我們來講一下 GraphQL Schema language 。這個和 GraphQL 的查詢語言類似。

一個 GraphQL schema 中的最基本的組件是對象類型,它表示你可以從服務上獲取到什麼樣類型的對象,以及對象的字段。

type Human {
	name: String!
	height: Float
	friends: [Person!]!
}

這裏我們定義了一個 Human 對象類型,這個對象中包括了幾個字段。 String Float 是內置的標量類型,String! 表示這個字段是非空的,[person!]! 表示一個 person 數組,他也是非空的,所以當你查詢 friends 時能得到一個數組,並且由於 Person!也是非空的,所以你可以得到的數組中每個項目都是一個 Person 對象.

GraphQL 對象類型上的每個字段都有可能有 0 或 多個參數

這裏所有的參數都是具名的

type Human {
	name: String!
	height:(unit: HeightUnit = METER) Float
	friends:[Person!]!
}

Schema 中有兩個特殊的類型 Query 和 Mutation 。

schema {
	query: Query
	mutation: Mutation
}

每個 GraphQL 服務都有一個 query 類型,可能有一個 mutation 類型。這兩個類型和常規對象類型無差,但是它們之所以特殊,是因爲它們定義了每一個 GraphQL 查詢的入口,這也是它們唯一特殊的地方,別的與普通對象類型無二致。

query {
	hero { name }
	person(id: 1) { name}
}
# -------->
type Query {
	hero: Charactor
	person(id: ID!): Charactor
}

標量類型(scalar type)

在之前我們就用到過好多次String Float 這些類型了,這些類型叫做標量類型,這些類型是沒有次級字段的,對象類型是有次級字段的。
GraphQL 自帶一組默認標量類型:
* Int:有符號 32 位整數。
* Float:有符號雙精度浮點值。
* String:UTF‐8 字符序列。
* Boolean:true 或者 false。
* ID:ID 標量類型表示一個唯一標識符,通常用以重新獲取對象或者作爲緩存中的鍵。ID 類型使用和 String 一樣的方式序列化;然而將其定義爲 ID 意味着並不需要人類可讀型。
我們還可以自定義標量類型,取決於我們的實現中如何定義將其序列化、反序列化和驗證。

scalar Date
# 例如定義一個Date 類型應該總是被序列化成整形時間戳,而客戶端應該知道去要求任何 date 字段都是這樣的格式

枚舉類型(enumeration type)

這個其實和別的語言中的枚舉類型是差不多的。枚舉類型是一種特殊的標量,它限制在一個特殊的可選值集合內。
1. 驗證這個類型的任何參數是可選值的某一個
2. 與類型系統溝通,一個字段總是一個有限值集合的其中一個值

enum Hobby {
	swim
	football
	basketball
}

類型修飾符

我們之前就已經看到過兩個了,分別是 ! [] 一個是用來標註 非空 ,一個是標註 數組
標記了非空的字段,服務器總會返回一個非空值,如果它得到一個空值,就會觸發一個 GraphQL 執行錯誤。如果定義的參數有這個非空標識,傳參時給個空值,會導致服務器返回一個驗證錯誤。
列表就相對來說直觀些了,通過[] 定義的就是一個數組了

接下來我們來看看這兩者結合使用的情況

myField: [String!]
# ------------- #
myField: null # 有效
myField: [] # 有效
myField: ['a','b'] # 有效
myField: ['a',null,'b'] # 錯誤
myField: [String]!
# ------------ #
myField: null # 錯誤
muField: [] # 有效
myField: ['a','b'] # 有效
myField: ['a',null,'b'] # 有效

結口(Interface)

GraphQL 支持接口,一個接口是一個抽象類型,它包含某些字段,而實現這個接口的對象類型必須包含這些字段

interface Human {
	id: ID!
	name: String
	age: Int
	height: Float
	friends:[Person!]!
}

實現 Human 接口

type Female implements Human {
	id: ID!
	name: String
	age: Int
	height: Float
	friends:[Person!]!
	feature: [String!]
}

type Male implements Human {
	id: ID!
	name: String
	age: Int
	height: Float
	friends: [Person!]!
	hobby: [String!]
}

聯合類型(Union type)

聯合類型和接口十分相似,但是它並不指定類型之間的任何共同字段,聯合類型的成員需要是具體對象類型,你不能使用接口或者其他聯合類型來創建一個聯合類型。

union searchResult = Human | Hero | Person

輸入類型(input type)

我們之前傳遞的參數都是一些標量類型或者是枚舉類型的值,但是我們不可避免的會傳遞一些複雜對象,比如在新增、更新操作中,這時候就引入了輸入對象類型,它和常規對象一樣,只是關鍵字是 input 而不是 type

input person {
	name: String
	age: Int
	...
}
mutation createPerson($person: Person){
	createOne(one: $person){
		name
		age
	}
}
# ---------- #
# person 
{
		name:'zs',
		age: 10
}

輸入對象類型上的字段本身也可以指代輸入對象類型,但是你不能在你的 schema 混淆輸入和輸出類型。輸入對象類型的字段當然也不能擁有參數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章