<Mutation /> refetchQueries "Unknown directive "_"."
<Mutation /> refetchQueries "Unknown directive "_"."
我正在使用 react-apollo
和 <Mutation />
组件与 refetchQueries
UPDATE_TASK
export const UPDATE_TASK = gql`
mutation updateTask(
$id: Int!
$title: String!
$priority: PriorityType!
$assigneeId: String!
$dueDate: Datetime!
$details: String!
$changedAt: Datetime!
) {
updateIssueTaskById(
input: {
id: $id
issueTaskPatch: {
title: $title
priority: $priority
assigneeId: $assigneeId
dueDate: $dueDate
details: $details
changedAt: $changedAt
}
}
) {
issueTask {
id
}
}
}
`;
const onUpdateTask = ({ render }) => <Mutation mutation={UPDATE_TASK} refetchQueries={[{query: GET_TASKS_BY_USER_ID}]} awaitRefetchQueries={true}>
{(mutation, result, ...rest) => render({ mutation, result, rest })}
</Mutation>
这按预期工作,初始突变发布,我们得到另一个查询,正如我们应该的那样:
导致问题的是 Query
:
请求负载
[{
"operationName": "getTasksByUserId",
"variables": {},
"query": "query getTasksByUserId($assigneeId: String!) {\n tasks: allIssueTasks(condition: {assigneeId: $assigneeId, status: OPEN}) @_(get: \"edges\") {\n edges @_(map: \"node\") {\n node {\n id\n title\n createdAt\n priority\n dueDate\n details\n status\n assigneeId\n creatorId\n __typename\n }\n __typename\n }\n __typename\n }\n}\n"
}]
回应
[{
"errors": [{
"message": "Unknown directive \"_\".",
"locations": [{
"line": 2,
"column": 76
}]
}, {
"message": "Unknown directive \"_\".",
"locations": [{
"line": 3,
"column": 11
}]
}]
}]
@_
指令不是内置指令,而是 graphql-lodash 添加的东西,这是一个实验性的客户端库,旨在任意转换 GraphQL 响应。该指令仅由库本身使用。在幕后,graphql-lodash
实际上在将请求发送到服务器之前删除了指令。如果它不这样做,服务器将收到一个它无法识别的指令并抛出一个验证错误,就像您看到的那样。
由于您看到验证错误,这意味着您根本没有使用 graphql-lodash,或者没有正确配置它。 here 提供了将库与 react-apollo
一起使用的说明。最简单的方法是使用自定义 link:
new ApolloLink((operation, forward) => {
const { query, transform } = graphqlLodash(operation.query);
operation.query = query;
return forward(operation)
.map(response => ({
...response,
data: transform(response.data),
}));
});
如果您要使用 refetch
或 refetchQueries
触发查询,您应该像上面那样使用 Link。使用包装器 HOC 将不起作用,因为查询将直接发送到服务器,而无需先由库进行转换。
我正在使用 react-apollo
和 <Mutation />
组件与 refetchQueries
UPDATE_TASK
export const UPDATE_TASK = gql`
mutation updateTask(
$id: Int!
$title: String!
$priority: PriorityType!
$assigneeId: String!
$dueDate: Datetime!
$details: String!
$changedAt: Datetime!
) {
updateIssueTaskById(
input: {
id: $id
issueTaskPatch: {
title: $title
priority: $priority
assigneeId: $assigneeId
dueDate: $dueDate
details: $details
changedAt: $changedAt
}
}
) {
issueTask {
id
}
}
}
`;
const onUpdateTask = ({ render }) => <Mutation mutation={UPDATE_TASK} refetchQueries={[{query: GET_TASKS_BY_USER_ID}]} awaitRefetchQueries={true}>
{(mutation, result, ...rest) => render({ mutation, result, rest })}
</Mutation>
这按预期工作,初始突变发布,我们得到另一个查询,正如我们应该的那样:
导致问题的是 Query
:
请求负载
[{
"operationName": "getTasksByUserId",
"variables": {},
"query": "query getTasksByUserId($assigneeId: String!) {\n tasks: allIssueTasks(condition: {assigneeId: $assigneeId, status: OPEN}) @_(get: \"edges\") {\n edges @_(map: \"node\") {\n node {\n id\n title\n createdAt\n priority\n dueDate\n details\n status\n assigneeId\n creatorId\n __typename\n }\n __typename\n }\n __typename\n }\n}\n"
}]
回应
[{
"errors": [{
"message": "Unknown directive \"_\".",
"locations": [{
"line": 2,
"column": 76
}]
}, {
"message": "Unknown directive \"_\".",
"locations": [{
"line": 3,
"column": 11
}]
}]
}]
@_
指令不是内置指令,而是 graphql-lodash 添加的东西,这是一个实验性的客户端库,旨在任意转换 GraphQL 响应。该指令仅由库本身使用。在幕后,graphql-lodash
实际上在将请求发送到服务器之前删除了指令。如果它不这样做,服务器将收到一个它无法识别的指令并抛出一个验证错误,就像您看到的那样。
由于您看到验证错误,这意味着您根本没有使用 graphql-lodash,或者没有正确配置它。 here 提供了将库与 react-apollo
一起使用的说明。最简单的方法是使用自定义 link:
new ApolloLink((operation, forward) => {
const { query, transform } = graphqlLodash(operation.query);
operation.query = query;
return forward(operation)
.map(response => ({
...response,
data: transform(response.data),
}));
});
如果您要使用 refetch
或 refetchQueries
触发查询,您应该像上面那样使用 Link。使用包装器 HOC 将不起作用,因为查询将直接发送到服务器,而无需先由库进行转换。