我正在深入研究GraphQL和Relay.到目前为止,对我而言,一切都相对顺利和容易理解.我有一个GraphQL架构Accounts
和Teams
.两者之间没有关系.我为帐户和团队的连接进行了一些特定于Relay的GraphQL调整.以下是这两个连接的示例查询...
{ viewer { teams { edges { node { id, name } } } accounts { edges { node { id, username } } } } }
我已经准备好了一个GraphQL变异,可以创建一个新帐户.这是GraphQL表示的......
type Mutation { newAccount(input: NewAccountInput!): NewAccountPayload } input NewAccountInput { username: String! password: String! clientMutationId: String! } type NewAccountPayload { account: Account clientMutationId: String! } type Account implements Node { id: ID! username: String! date_created: String! }
我现在正在尝试创建使用此GraphQL突变的客户端中继突变.不过,我对如何正确地做到这一点感到很困惑.我已经按照例子,我想出的任何事情似乎都没有正确运行.我倾向于得到与片段组成有关的错误.
如果我正在编写使用此GraphQL突变的Relay突变,那么相应的mutator配置会是什么?我应该用RANGE_ADD
吗?
对于您的客户端变异,您可以使用以下内容:
export default class AddAccountMutation extends Relay.Mutation {
static fragments = {
viewer: () => Relay.QL`
fragment on Viewer {
id,
}
`,
};
getMutation() {
return Relay.QL`mutation{addAccount}`;
}
getVariables() {
return {
newAccount: this.props.newAccount,
};
}
getFatQuery() {
return Relay.QL`
fragment on AddAccountPayload {
accountEdge,
viewer {
accounts,
},
}
`;
}
getConfigs() {
return [{
type: 'RANGE_ADD',
parentName: 'viewer',
parentID: this.props.viewer.id,
connectionName: 'accounts',
edgeName: 'accountEdge',
rangeBehaviors: {
'': 'append',
},
}];
}
getOptimisticResponse() {
return {
accountEdge: {
node: {
userName: this.props.newAccount.userName,
},
},
viewer: {
id: this.props.viewer.id,
},
};
}
}
然后,在GraphQL架构中,您需要返回新创建的边以及光标:
var GraphQLAddAccountMutation = mutationWithClientMutationId({ name: 'AddAccount', inputFields: { newAccount: { type: new GraphQLNonNull(NewAccountInput) } }, outputFields: { accountEdge: { type: GraphQLAccountEdge, resolve: async ({localAccountId}) => { var account = await getAccountById(localAccountId); var accounts = await getAccounts(); return { cursor: cursorForObjectInConnection(accounts, account) node: account, }; } }, viewer: { type: GraphQLViewer, resolve: () => getViewer() }, }, mutateAndGetPayload: async ({ newAccount }) => { var localAccountId = await createAccount(newAccount); return {localAccountId}; } }); var { connectionType: AccountsConnection, edgeType: GraphQLAccountEdge, } = connectionDefinitions({ name: 'Account', nodeType: Account, });
您需要将getAccounts(),getAccountById()和createAccount方法调用替换为您的服务器/后端使用的任何内容.
可能有一种更好的方法来计算游标而不必多次执行服务器,但请记住,Relay帮助器cursorForObjectInConnection不会对对象进行任何深度比较,因此如果您需要通过id查找帐户在列表中,您可能需要进行自定义比较:
function getCursor(dataList, item) { for (const i of dataList) { if (i._id.toString() === item._id.toString()) { let cursor = cursorForObjectInConnection(dataList, i); return cursor; } } }
最后,将GraphQL变异添加为"addAccount"到您的架构变异字段,该字段由客户端变异引用.