2016-01-11 36 views

Odpowiedz

1

Sematic z GraphQLInterfaceType jest jak większość języków programowania interface. a graphql dodaje do niego więcej zachowań. jak sprawdzić, czy klasa pochodna implementuje wszystkie pola, dynamiczne rozwiązywanie do instancji pochodnej.
sematic z GraphQLUnionType nie jest Union, ale coś OR. (Trochę jak typ kontroli na flowtype jest?)
Prawdziwy świat jest przykładem example in Relay => projekt węzła przekaźnika.
GraphQLInterfaceType jest całkowicie niepowiązane z GraphQLUnionType.
Myślę, że byłeś przez to zdezorientowany?

interface Node{ 
    id: string 
} 

type Dog implements Node{ 
    id: string 
} 
type Cat implements Node{ 
    id: string 
} 
union Animal = Dog | Cat 

type User{ 
    node: Node 
    animal: Animal 
} 

Jeśli mylić o to, powinieneś dostać jakąś książkę wulgaryzmów typu czytać. (Jak C# lub Java lub coś innego. Może powinieneś rzucić okiem na przepływ za to wykorzystanie Dog|Cat jest ograniczenie typu)

17

Oba mają pomóc w zaprojektowaniu schematu z heterogenicznym zbiorem typów, a można osiągnąć tę samą funkcjonalność przy użyciu obu, ale GraphQLInterfaceType jest bardziej odpowiedni, gdy typy są w zasadzie takie same, ale niektóre z pól są różne, i GraphQLUnionType, gdy typy są całkowicie różne i mają zupełnie różne pola.

Ostatecznie, czy użyć jednego lub drugiego w zależności od projektu schematu.

Przykładowo, powiedzmy, że masz listę blogów, ale blogi korzystające z frameworka A używają nazwy użytkownika i hasła jako uwierzytelniania, a blog używający frameworka B używa adresu e-mail i hasła. Projektujemy je z GraphQLInterfaceType tak:

const BlogType = new GraphQLInterfaceType({ 
    name: 'Blog', 
    fields: { 
    url: { type: new GraphQLNonNull(GraphQLString) } 
    password: { type: new GraphQLNonNull(GraphQLString) } 
    }, 
    resolveType: resolveBlogType 
}); 

const BlogAType = new GraphQLObjectType({ 
    name: 'BlogA', 
    interfaces: [Blog], 
    fields: { 
    url: { type: new GraphQLNonNull(GraphQLString) } 
    username: { type: new GraphQLNonNull(GraphQLString) }, 
    password: { type: new GraphQLNonNull(GraphQLString) } 
    } 
}); 

const BlogBType = new GraphQLObjectType({ 
    name: 'BlogB', 
    interfaces: [Blog], 
    fields: { 
    url: { type: new GraphQLNonNull(GraphQLString) } 
    email: { type: new GraphQLNonNull(GraphQLString) }, 
    password: { type: new GraphQLNonNull(GraphQLString) } 
    } 
}); 

function resolveBlogType(value) { 
    return value.username ? BlogAType : BlogBType; 
} 

Kiedy tworzymy nowy blog wysyłania username, stworzy BlogA.

Możemy zapytać tak:

query MyQuery { 
    blogs: { 
    url 
    password 
    ... on BlogA { 
     email 
    } 
    ... on BlogB { 
     username 
    } 
    } 
} 

Teraz przejdźmy taką samą funkcjonalność, ale stosując GraphQLUnionType, bo wolimy używać po prostu jeden rodzaj bloga oraz 2 rodzaje metod uwierzytelniania:

const AuthAType = new GraphQLObjectType({ 
    name: 'AuthA', 
    fields: { 
    username: { type: new GraphQLNonNull(GraphQLString) }, 
    password: { type: new GraphQLNonNull(GraphQLString) } 
    } 
}); 

const AuthBType = new GraphQLObjectType({ 
    name: 'AuthB', 
    fields: { 
    email: { type: new GraphQLNonNull(GraphQLString) }, 
    password: { type: new GraphQLNonNull(GraphQLString) } 
    } 
}); 

const AuthType = new GraphQLUnionType({ 
    name: 'Auth', 
    types: [AuthAType, AuthBType] 
    resolveType: resolveAuthType 
}); 

const BlogType = new GraphQLInterfaceType({ 
    name: 'Blog', 
    fields: { 
    url: { type: new GraphQLNonNull(GraphQLString) } 
    auth: { type: AuthType } 
    }, 

}); 

function resolveAuthType(value) { 
    return value.username ? AuthAType : AuthBType; 
} 

Możemy zapytać tak:

query MyQuery { 
    blogs: { 
    url 
    auth { 
     ... on AuthA { 
     username 
     password 
     } 
     ... on AuthB { 
     email 
     password 
     } 
    } 
    } 
} 

jak widać w w tym przykładzie osiągamy to samo z interfejsem lub złączem, ale jeden lub drugi może być bardziej odpowiedni w zależności od projektu schematu.

Załóżmy na przykład, że chcesz dodać strukturę blogu C, która również używa adresu e-mail i hasła. Będziesz musiał dołączyć inne pole, aby odróżnić je od bloga B w naszej funkcji resolveBlogType. Dodajmy pole type. W naszym przykładzie unijnym, ponieważ mamy dostęp tylko do pól w Unii, należy dodać do Unii type. Gdyby w przyszłości chcieliśmy dodać kolejną Unię z tymi samymi polami dla wielu frameworków, musielibyśmy również dodać tam pole type. Niezbyt miłe, że w naszym schemacie są wielokrotnie powielane. Lepszym rozwiązaniem może być użycie interfejsu i posiadanie pojedynczego pola type dostępnego w funkcji resolveBlogType przez wszystkie obiekty korzystające z interfejsu.

+0

kiedy szukasz "blogów" na fragmencie przekaźnika, co to odpowiada grafql-mądry? Widzę, że twój typ interfejsu grafql nazywa się 'Blog' – maxwell

+0

Musisz utworzyć zapytanie' blogs', którego nie ma w przykładowym kodzie –

+0

Wciąż nie jestem pewien, czy rozumiem – arcom