一個GraphQL的query語法可能會長得像這樣:
{
me {
name
appearsIn
}
}
和他的回傳結果可能會是長這樣:
{
"data": {
"me": {
"name": "R2-D2",
"appearsIn": [
"NEWHOPE",
"EMPIRE",
"JEDI"
]
}
}
}
上面是一個簡單的查詢語法,而我們所得到的資料會在data這個欄位去作呈現。而內部的結構則取決於我們所寫的結構,以及field是如何去定義的。
不難發現,回傳的資料本身是json格式,不管是在哪個語言下,都十分方便去做使用。
在我們去實作一個graphQL API時,首先必須先去定義他的schema,像是以下這樣:
type Hero {
id: Int!
name: String!
appearsIn: [String!]
}
type Query {
me: Hero
allHeros: [Hero]
}
在schema中,我們會去定義我們各個type的結構,而定義結構的同時,也決定了我們必須如何去下我們的語法。
以上述例子來說,Hero 跟 Query稱為Object type,而Int這種就稱為scalar type。
在graphQL中,有以下幾種scalar type。
看起來也許很複雜,但可以簡單理解成,scalar type就是我們最後會抓到的資料,而object type則是可以繼續往下去抓,而一個object type底下會由一個以上的field(可能是object type 或是scalar type)所組成
Query是每個graphql都會有的root底下最頂層的Object type,也就是我們的查詢語法,基本都放在這裡面。
我們可以看到Query裡面,有兩個field,分別是me跟allHero,在這邊,可以簡單理解成,他給了你兩種查詢語法:me 跟 allHero,而這兩個語法的功能是甚麼呢???
我們不知道,對,不知道。
在schema中,我們只去定義我們type的內容結構,並不會去決定我們的query是回傳甚麼資料。(但依照名稱,可以先把me理解成會回傳自己的Hero type的資料,而all Hero則會回傳所有的Hero Type的資料)
現在我們回去看一開始的例子:
{
me {
name
appearsIn
}
}
這個語法,其實等同於:
query {
me {
name <= 這行可以選擇性的不寫
appearsIn <= 這行可以選擇性的不寫
}
}
這樣就清楚多了,query是第一層的type,他的下一層,是me或是allHeros,然後因為me是Hero這個type,因此下面還有name跟appearsIn這兩個field,我們在查詢語法中,可以選擇性的決定要不要印出這兩個語法(是我們需不需要這個欄位來決定)。
而query語法跟SQL語法也是可以下條件的,例如:
query {
allHeros(id: 2) {
name <= 這行可以選擇性的不寫
appearsIn <= 這行可以選擇性的不寫
}
}
這樣的話,id為2的Hero就會被抓出來(因為allHeros的type是[Hero],這代表我們會抓到一個Hero type資料的陣列)。
而我們又要怎麼決定me跟allHeros是抓到那些資料呢? 這則是交給一個叫做resolver的東西,他負責根據我們的query語法,根據我們撰寫的規則去解析我們要回傳的資料。
因此,明天我們用rails來寫一個簡單的query的api