helfer / apollo-link-debounce Goto Github PK
View Code? Open in Web Editor NEWAn Apollo Link that debounces requests
License: MIT License
An Apollo Link that debounces requests
License: MIT License
Would be nice if we could set the debounce time on the query level, instead of global scope. Or perhaps bound to a debounceKey
?
My prefered way. Specify the delay in the query, and thereby close to the implementing components:
const op = {
query: gql`mutation slide($val: Float){ moveSlider(value: $val) }`,
variables: { val: 99 }
context: {
debounceKey: 'Slide',
debounceDelay: 300,
},
};
Alternative option that could be usefull. Supply a key-delay-map
as second argument to the link constructor:
const DEBOUNCE_TIMEOUT = 100;
this.link = ApolloLink.from([
new DebounceLink(DEBOUNCE_TIMEOUT, {
Slide: 300,
}),
new HttpLink({ uri: URI_TO_YOUR_GRAPHQL_SERVER }),
]);
code example:
This is optimistic query
return {
__typename: 'Mutation',
updateBlockItemField: {
__typename: 'Resume',
...resume,
id: resumeId,
updatesCount: resume.updatesCount + 1,
details: {
___typename: 'ResumeDetails',
...resume.details,
},
settings: {
___typename: 'ResumeSettings',
...resume.settings,
},
blocks: resume.blocks,
},
};
This is Mutation:
save = debounce(value => {
const { mutate, variables, optimisticResponse, update, isCoverLetter } = this.props;
const options = {
variables: {
...variables,
value,
},
context: {
debounceKey: generateDebounceKey(variables),
},
}
if (optimisticResponse) options.optimisticResponse = optimisticResponse(value);
mutate(options);
}, 30);
And this is my init
return new ApolloClient({
connectToDevTools: isBrowser,
ssrMode: !isBrowser, // Disables forceFetch on the server (so queries are only run once)
link: ApolloLink.from([
onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors) {
graphQLErrors.map(({ message, locations, path }) =>
console.error(`[GraphQL error]: Message: ${message}, Path: ${path}`),
);
}
if (networkError) {
console.error(`[${networkError.name}]: Status: ${networkError.statusCode}: Message: ${networkError.message}`);
}
}),
new DebounceLink(1000),
authLink.concat(
ApolloLink.split(
operation => operation.getContext().client === 'coverLetter', // Routes the query to the proper client
coverLetterLink,
httpLink,
),
),
]),
cache,
resolvers: {},
});
Hi! I tried apollo-link-debounce on @apollo/client, but the packages have slightly changed. In particular, ApolloLink
is now part of @apollo/client
(rather than apollo-link
), and a few fields have been added (onError
and setOnError
, which seems to be very small functions - probably inheritable?).
Currently, for mutations, when the debounce timeout is reached and a request is sent, if the the same request is queued again while the first's request is in network flight, then a mutation result will be returned that overrides the requests queued since.
The solution to this is to cancel any in-flight requests with an abortController whenever a new request is enqueued.
This article is a pretty decent write-up: https://evilmartians.com/chronicles/aborting-queries-and-mutations-in-react-apollo
No idea if it's even possible. But currently, react-apollo
is providing a loading
state while the query is running. Would be nice if this link could add a waiting
(or debouncing
) state while the query is being delayed in the debounce.
Would you be ok with merging the variables
object for all queued requests when flushing the queue? It seems to me that for cases where you're updating an object instead of a single value that would be the desired behaviour. Happy to take a crack at it if you're open.
Some warnings like this are thrown when the last request is executed after some debounced requests:
When I remove the DebounceLink, these warnings disappear.
const link = ApolloLink.from([
new DebounceLink(100),
new HttpLink({ uri: process.env.GRAPHQL_URL! }),
])
export default class TaskListItem extends React.Component<TaskListItemProps> {
public static fragment = gql`
fragment TaskItemFragment on Task {
id
done
message
}
`
public render() {
const { task } = this.props
const debounceOptions = { debounceKey: task.id, debounceTimeout: 500 }
if (task.done) {
return (
<Mutation<UncompleteTask, UncompleteTaskVariables>
mutation={UNCOMPLETE_TASK}
optimisticResponse={{
uncompleteTask: {
__typename: 'Task',
done: false,
id: task.id,
},
}}
variables={{ id: task.id }}
context={debounceOptions}
>
{uncompleteTask => (
<Task
checked
actions={<DeleteTaskButton taskId={task.id} />}
onCheck={() => uncompleteTask()}
>
<Text>{task.message}</Text>
</Task>
)}
</Mutation>
)
}
return (
<Mutation<CompleteTask, CompleteTaskVariables>
mutation={COMPLETE_TASK}
optimisticResponse={{
completeTask: {
__typename: 'Task',
done: true,
id: task.id,
},
}}
variables={{ id: task.id }}
context={debounceOptions}
>
{completeTask => (
<Task
actions={<DeleteTaskButton taskId={task.id} />}
checked={false}
onCheck={() => completeTask()}
>
<Text>{task.message}</Text>
</Task>
)}
</Mutation>
)
}
}
Hello,
I'm using a DebounceLink on the client and server, and if I understand it correctly the link is used to not send 2 same queries on a given interval.
Then, we figured out that the debounce on the server impacts the server response time. I would like to know your experiences if any, doing SSR with Apollo Client? Do you advice me to not use there?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.