问题
I need to change my mutation document dynamically to be able to create multiple items in a single mutation. So I have this function createOrderName
that takes an integer and be able to create the correct mutation document. Eg. createOrderName(2)
gets
mutation createOrderMut($input0: AddToOrderMenuItemConnectionInput!, $input1: AddToOrderMenuItemConnectionInput!) {
input0: addToOrderMenuItemConnection (input:$input0) {
changedOrderMenuItem {
id
}
}
input1: addToOrderMenuItemConnection (input:$input1) {
changedOrderMenuItem {
id
}
}
}
And my container is as follow.
const CartContainer = compose(
graphql(createOrderName(2), {
props: ({ mutate }) => ({
addToOrderMenuItem: (menus, orderId) => mutate({
variables: createOrdersInput(menus, orderId)
})
})
})
)(CartView)
Now how can I pass an integer value to this mutation in order for it to create the correct mutation document? Currently it's fix to 2, but I need it to be more flexible so I can create any number of items...
回答1:
This sounds like an unfortunate limitation of the backend you're working with. The right way to do a batch mutation would be to have a single mutation field on the server that accepts a list argument with all of the items you want to insert. Thus, Apollo isn't designed to support such dynamic query generation with the standard react-apollo
API. That's because we strongly believe that working with static queries is much better than generating fields at runtime: https://dev-blog.apollodata.com/5-benefits-of-static-graphql-queries-b7fa90b0b69a#.hp710vxe7
Given the situation, though, sounds like generation the mutation string dynamically is a good option. You can do this by using Apollo directly instead of through the graphql
HoC. You can use the withApollo
HoC to do this: http://dev.apollodata.com/react/higher-order-components.html#withApollo
import { withApollo } from 'react-apollo';
const MyComponent = ({ client }) => {
function mutate() {
const dynamicMutationString = // generate mutation string here
client.mutate({
mutation: gql`${dynamicMutationString}`,
variables: { ... },
}).then(...);
}
return <button onClick={mutate}>Click here</button>;
}
const MyComponentWithApollo = withApollo(MyComponent);
We built this extra API for just this purpose - when the standard stuff is not enough.
Here are the docs for mutate
btw: http://dev.apollodata.com/core/apollo-client-api.html#ApolloClient.mutate
回答2:
I'm not sure if I can answer your question with your current implementation, so I'm going to urge you to rethink your mutation definition and use GraphQLList
and GraphQLInputObject
.
So, depending on the fields you need to mutate:
args: {
input: {
type: new GraphQLList(new GraphQLInputObjectType({
name: 'inputObject',
description: 'Your description here',
fields: {
id: { type: GraphQLInt }
},
})),
},
},
This way you can provide n-number of objects into your mutate call, and get a list back on your type:
{
mutation myMutation {
addToOrderMenuItemConnection(input: [{ id: 123 }, { id: 456 }]) {
id
}
}
}
Again, I'm not 100% familiar with your end-goal, but I think this would give you flexibility for future changes/updates as well since you're dealing with an object input rather than individual arguments, which would also (hopefully) insulate you from future breaking-changes.
来源:https://stackoverflow.com/questions/41993034/dynamic-mutation-document-for-react-apollo