這聽起來像你真的已經接近你想要的東西了。我認爲使用投票類型作爲用戶和投票間的中間人是一個很好的解決方案。這樣做,這樣會讓你發出一個看起來像這樣的查詢:
// Direction 1: User -> Vote -> Poll
query GetUser($id: "abc") {
getUser(id: $id) {
username
votes(first: 10) {
edges {
node {
value
poll {
name
}
}
cursor
}
}
}
}
// Direction 2: Poll -> Vote -> User
query GetPoll($id: "xyz") {
getPoll(id: $id) {
name
votes(first: 10) {
edges {
node {
value
user {
username
}
}
cursor
}
}
}
}
在這個例子中,您的投票類型是存儲沿着邊緣的信息的實體。 「列表上的連接」的一個優點是您可以沿邊存儲信息,這是正確的,但我認爲更大的好處是能夠通過大量對象進行分頁。
要在服務器上實現此功能,您必須爲User和Poll上的Connection字段(即上面示例中的'votes'字段)編寫自定義解析方法。取決於你如何存儲你的數據,這將改變,但這是一個想法的一些僞代碼。
type Vote {
value: String,
poll: Poll, // Both poll & user would have resolve functions to grab their respective object.
user: User
}
type VoteEdge {
node: Vote,
cursor: String // an opaque cursor used in the 'before' & 'after' pagination args
}
type PageInfo {
hasNextPage: Boolean,
hasPreviousPage: Boolean
}
type VotesConnectionPayload {
edges: [VoteEdge],
pageInfo: PageInfo
}
const UserType = new GraphQLObjectType({
name: 'User',
fields:() => ({
id: {
type: new GraphQLNonNull(GraphQLID),
description: "A unique identifier."
},
username: {
type: new GraphQLNonNull(GraphQLString),
description: "A username",
},
votes: {
type: VotesConnectionPayload,
description: "A paginated set of the user's votes",
args: { // pagination args
first: {
type: GraphQLInt
},
after: {
type: GraphQLString
},
last: {
type: GraphQLInt
},
before: {
type: GraphQLString
}
}
resolve: (parent, paginationArgs, ctxt) => {
// You can pass a reference to your data source in the ctxt.
const db = ctxt.db;
// Go get the full set of votes for my user. Preferably this returns a cursor
// to the set so you don't pull everything over the network
return db.getVotesForUser(parent.id).then(votes => {
// Assume we have a pagination function that applies the pagination args
// See https://facebook.github.io/relay/graphql/connections.htm for more details
return paginate(votes, paginationArgs);
}).then((paginatedVotes, pageInfo) => {
// Format the votes as a connection payload.
const edges = paginatedVotes.map(vote => {
// There are many ways to handle cursors but lets assume
// we have a magic function that gets one.
return {
cursor: getCursor(vote),
node: vote
}
});
return {
edges: edges,
pageInfo: pageInfo
}
})
}
}
})
});
你將不得不在你的投票類型的反方向同樣做一些事情。要將對象添加到連接,您只需創建一個指向正確的用戶和帖子的Vote對象。 db.getVotesForUser()方法應該足夠聰明,以實現這是一對多連接,然後可以拉出正確的對象。
創建一個處理連接的標準方式可能是一項艱鉅的任務,但幸運的是,有些服務可以幫助您開始使用GraphQL,而無需自己實現所有後端邏輯。我爲其中一項服務https://scaphold.io工作,如果您有興趣,我會很樂意與您進一步討論此解決方案。
「如果這是重要的,選民和他的調查之間的關係應該是雙向的,即每個用戶連接到他的投票調查,每個調查連接到其選民「。 - 是的,這看起來很重要。邊緣是特定於連接的,並且您在這裏有兩個連接,因此每個連接都需要明確的邊緣。如果選民投票 - 投票關係存在兩個真相,那麼真相的來源在哪裏? – wincent
我明白你在說什麼,我只是將投票類型看作額外的中介,因爲我已經有了連接,但你可能是對的。 –