2017-04-17 44 views
4

爲什麼GraphQL implements關鍵字需要重複的字段,是強制性的嗎?就像文件中的例子:爲什麼GraphQL`implements`需要複製這些字段,這是強制性的嗎?如果是,那麼根本原因是什麼?

enum Episode { NEWHOPE, EMPIRE, JEDI } 

interface Character { 
    id: String 
    name: String 
    friends: [Character] 
    appearsIn: [Episode] 
} 

type Human implements Character { 
    id: String 
    name: String 
    friends: [Character] 
    appearsIn: [Episode] 
    homePlanet: String 
} 

type Droid implements Character { 
    id: String 
    name: String 
    friends: [Character] 
    appearsIn: [Episode] 
    primaryFunction: String 
} 

如果是的話,是什麼原因造成的?

堂妹如果我要重複,如果我改變的話,我需要改變無處不在......

回答

7

是的,這根據當前spec是強制性的:

對象類型必須包括相同名稱的字段用於在接口中定義的每個字段。

它允許您更精確地指定派生類型中的字段類型。可以將字段更改爲非空或接口或聯合的某個特定子類型。以你爲例,假設人類只與其他人類交朋友,而與機器人相同。那麼下面的模式是有效的。

interface Character { 
    id: String 
    name: String 
    friends: [Character] 
    appearsIn: [Episode] 
} 

type Human implements Character { 
    id: String 
    name: String 
    friends: [Human] # <- notice Human here 
    appearsIn: [Episode] 
    homePlanet: String 
} 

type Droid implements Character { 
    id: String 
    name: String 
    friends: [Droid!]! # <- specified Droid here + added not null 
    appearsIn: [Episode] 
    primaryFunction: String 
} 

對象字段可能包含未在接口字段中定義的其他參數(但不得要求任何附加參數)。

退房規範的更多詳細信息:Object type validation

2

是的,它是強制性的。如果有幫助,可以將它看作類似於Java類和接口的類。接口有類型簽名,但不能有實現。它在你寫出所有實現的類中,並且類型簽名被重複。這使您能夠在類型簽名中選擇子類型或協變類型,因此它們可能不是,而是完全相同的

現在假設您正在使用來自graphql-js的JavaScript對象創建GraphQL架構。接口只是字段名稱和類型。對象類型定義本身具有「實現」或resolveresolveType以及實際使其成爲可執行模式的其他屬性。

但是,您的示例使用模式語言,而不是「實現」。所以他們幾乎是一個確切的重複彼此。你不一定需要每次都拼出來,你可以使用字符串插值來分享接口的一部分。

const characterFields = ` 
    id: String 
    name: String 
    friends: [Character] 
    appearsIn: [Episode] 
` 

const typeDefs = ` 
    interface Character { 
    ${characterFields} 
    } 

    type Human Implements Character { 
    ${characterFields} 
    homePlanet: String 
    } 
` 

編輯:類似於在Java比較,字段可能不準確相同的類型。正如RomanHotsiy指出的那樣,您可以使類型不可爲空或使用多態類型的子類型。

+0

非常感謝您的回答和比較的強大,但只有一個答案可以選擇,組合將是最好的。 – lnshi

+0

@ andy-carlson 有一個外部文件包含'character'和'Human'的公共字段,然後添加到像'... characterFields'這樣的字段之間有何區別? –