2017-05-27 7 views
0

Ich baue eine graphql-Anwendung, wo eine User eine Reihe von Entries haben kann. Es ist eine n-zu-m-Beziehung, wobei die Zwischentabelle/-kante zusätzliche Informationen über die Beziehung enthält. Mein graphql Schema sieht wie folgt aus:Modeling Relay Cursor Connections

type User { 
    id: ID!, 
    entries(…): [UserEntry] 
} 

type UserEntry { 
    id: ID!, 
    user: User, 
    entry: Entry, 
    someOtherAttribute: String, 
    yetAnotherAttribute: String 
} 

type Entry {...} 

type Query { 
    me: User! 
    userEntry(userEntryId: ID!): UserEntry! 
} 

Ich möchte, dass entries Feld Cursor Stil Paginierung hinzuzufügen, die Relay Cursor Connections Specification folgen. Also ich denke, UserEntry so etwas wie diese werden würde:

type UserEntryEdge { 
    node: Entry, 
    cursor: String, 
    someOtherAttribute: String, 
    yetAnotherEdgeAttribute: String 
} 

Aber ich will noch in der Lage sein, die UserEntry/UserEntryEdge direkt abgefragt werden, und in diesem Zusammenhang das cursor Feld zum Beispiel wäre irrelevant.

Was ist der beste Weg, um mein Graphql-Schema zu entwerfen, um Kanten Daten direkt abfragen zu können?

(FYI: Ich verwende NodeJS und die apollo Rahmen Suite sowohl auf Server und Client)

+0

Sie wollen also 'Entry' direkt abfragen? Und was meinst du unter ** direkt **? Können Sie Beispielabfragen bereitstellen, die Sie ausführen möchten? – RomanHotsiy

+1

Ich könnte 'Eintrag' hier gut in Frage. Ich möchte noch UserEntry abfragen können! Ich habe die Definition meiner aktuellen Abfragen hinzugefügt. Dank – kombucha

Antwort

1

Sie werden tatsächlich modellieren Ihr Schema wie diese

[User] hasAndBelongsToMany [Entry] 

Aber man könnte darüber nachdenken, es wie

[User] hasMany [UserEntry] hasOne [Entry] 
    and 
[Entry] hasMany [UserEntry] hasOne [User] 

So, zurück zu Ihrem GraphQL Schema:

type User { 
    id: ID!, 
    userEntriesConnection(…): UserEntriesConnection! 
} 

type UserEntriesConnection { 
    edges: [UserEntryEdge]!, 
    pageInfo: ... 
} 

type UserEntryEdge { 
    cursor: String!, 
    node: UserEntry, 
} 

type UserEntry { 
    id: ID!, 
    user: User, 
    entry: Entry, 
    someOtherAttribute: String, 
    yetAnotherAttribute: String 
} 

type Entry { ... } 

type Query { 
    me: User! 
    userEntry(userEntryId: ID!): UserEntry! 
} 

Würde das zu Ihrem Bedarf passen? Die Abfragen wären ausführlicher, weil es mehr Tiefe gibt, aber vollständiger.

+0

Dies scheint wie eine gute Problemumgehung. Vielen Dank ! – kombucha

0

Wenn Sie noch UserEntry müssen direkt abfragen dann denke ich, Sie es als eine separate Art halten sollte in Ihr Schema und wandelt es nicht in Edge Typ um.

Also behalten Sie beide UserEntry und UserEntryEdge.

kann das resultierende Schema wie folgt aussehen:

type User { 
    id: ID!, 
    entries(…): [UserEntryConnection] 
} 

type UserEntryConnection { 
    edges: [UserEntryEdge] 
    nodes: [Entry] # shortcut (GitHub does like that) 
    pageInfo: PageInfo! 
} 

type UserEntryEdge { 
    node: Entry, 
    cursor: String, 
    info: UserEntry # To not duplicate attributes, you can use UserEntry type here 
} 

type UserEntry { 
    id: ID!, 
    user: User, 
    entry: Foo, 
    someOtherAttribute: String, 
    yetAnotherAttribute: String 
} 

type Entry {...} 

type Query { 
    me: User! 
    userEntry(userEntryId: ID!): UserEntry! # keep userEntry field as is 
} 
+0

Ich habe darüber nachgedacht, es so zu machen, aber es fühlt sich ein bisschen peinlich für mich an, dass "Entry" sowohl vom Feld "node" von "UserEntryEdge" als auch vom Feld "entry" von "UserEntry" erreichbar ist. Vielleicht sollte ich nur eine zusammengeführte Version von "Entry" und "UserEntry" in der A ... Vielen Dank für Ihre Hilfe – kombucha