I saw that in the middleware the req
object has a request
object with operationName
.
{query: Object, variables: Object, operationName: "Search"}
So I'm figuring out a way to cancel previous request with the same operationName.
The motivation behind is to use this feature on search's autocomplete/suggestions.
So when a new query is made we cancel the last request if it is not completed yet, so make it easy to treat the asynchronism in the frontend.
@lucasfeliciano in a sense this already happens. If the same component makes queries in quick succession, server responses from previous requests are ignored when there's a more recent request already under way. What more would you need?
I was having this conversation at work today. What about these two cases:
@joefraley there's no way for us to cancel the request once it's been sent to the server. That would require specific logic on the server that we have no control over. Currently Apollo Client will receive the result, but it will throw it away if it's not the most recent request made by an active observable query.
I'm closing this since it seems the feature requested is already implemented 馃檪
@helfer I understand that users would need to implement their own server side logic to handle the cancellation. But that's only possible if the Apollo client fires a cancellation.
With no client cancellation, there is no way to handle the desired case. With client cancellation, people that need it can account for it on the server, and people that don't need it will not notice any change from the present day behavior.
I'm assuming that the client can't cancel because it's using the native fetch API today, so I guess this proposal is partly to use a different request method that permits cancellation (like axios or the native XHR).
@helfer I have to agree with @joefraley
Support this on client side is kinda a must have feature for big and high quality applications
@helfer @lucasfeliciano it's possible to set up your own custom network interface that does support cancellation if you're using apollo-react, but it requires rebuilding the apollo-client network layer and extending its API. I don't know if other Apollo libraries support that idea or not.
My product can't support GraphQL without cancellation.
Another possibility is to set your cancellation endpoints aside from gql. So keep hitting a one of rest point for search, but gql your other stuff. That only works if a limited subset of your app needs cancellation though.
Indeed, I think we should have this implemented in apollo client it self.
Passing a boolean in the options object of the graphql()
method or in the network interface to enable this in a specific query or globally, the tricky part is that we need cancel the request only for that type of query.
I need to think about this, I might play with the request object since the same has the operationName
:
{query: Object, variables: Object, operationName: "Search"}
Which is the query name
It looks like it's not hard to implement custom network interface which extends HttpFetchNetworkInterface
And override fetchFromRemoteEndpoint
method, use inside XMLHttpRequest
and do custom logic with request abort
The latest version of the fetch API is cancellable (implemented in Firefox and Edge, easy to polyfill): https://developer.mozilla.org/en-US/docs/Web/API/AbortController
Any plans to implement that?
In my project, I also need that feature. I launch a query but i would be able to cancel it depending on user action .... Do you think that this feature will be implemented ?
I think this feature is really needed. For example, lets say some private data is being fetched and user clicks logout. With a slow network, we could have a race condition, when private data would arrive after user logged out. Aborting a pending request in the case like this would prevent such a disaster.
Heeey! @helfer Is there news about it? Could it be done?
Running into this problem now in relation to data coming back to unmounted components. Looks like Dan's in favour of cancellation for api libraries.
I think this issue should at the very least be reopened now that it is possible to cancel fetches with AbortController. As Dan pointed out in the above link, there are many classes of problems which are best solved by canceling the ongoing request.
And since most browsers and modern CDNs have HTTP/2 support, those requests can often be canceled without ending the connection and without the server sending any unwanted data.
Please reopen this issue.
Request cancellation from the client offers many benefits including but not limited to:
There is ample precedent for adding cancellation to asynchronous APIs.
Guys I believe this was implemented as part of Apollo link. Check the source code : https://github.com/apollographql/apollo-link/blob/master/packages/apollo-link-http/src/httpLink.ts
@stalniy this would probably work if observable responsible for a request is cancelled (abort would be triggered then), but does it ever happen actually? lets say we have a query
pending and before it finished, a component just unmounted - I guess this query will finish executing and abort will never be triggered
@stalniy I'm using the unsubscribe()
method of the Observer generated by apollo, and it doesn't kill the query at all.
The callback isn't triggered because I unsubscribed it, but apollo is still polling for the server's answer.
I'm using it inside of an autocomplete component, and I unsubscribe the previous subscription each time I type a key.
But instead of killing previous fetches, they pile up and the more I type, the longer it takes to display the results (because all the queries are executed and the final result only displays at the end).
However, when I copy/paste an entire word, as it triggers only one request, it's blazing fast.
So... there's still a need for this feature. The unsubscribe()
method should abort the fetch query.
Same problem here. I have an autocomplete where every keystroke changes/re-fires the query. At the moment I unsubscribe in a delayed timeout function to avoid that issue, which is VERY ugly and unreliable.
Is there any property on the subscription which indicates wether the subscription is already in an "unsubscribeable" state?
Thanks!
Any news re potential introducing of requests aborts? For REST APIS, I am heavy user of Redux-Saga, and I really appreciate control which it gives me - saga aborts, effects like takeLastest, takeEvery, all, race
, which give awesome control which can prevents subtle race condition bugs, especially on mobile devices.
I really like Apollo and I think that it is really the future of the way apps should be written, but because it is declarative, we dont have much networking control, Apollo does all the lifting for us, but this has a cost, and I believe that introducing aborts, takeLastest, takeEvery, all, race
counterparts would be a missing puzzle to the equation.
To help provide a more clear separation between feature requests / discussions and bugs, and to help clean up the feature request / discussion backlog, Apollo Client feature requests / discussions are now being managed under the https://github.com/apollographql/apollo-feature-requests repository.
Migrated to: https://github.com/apollographql/apollo-feature-requests/issues/40
Most helpful comment
I think this feature is really needed. For example, lets say some private data is being fetched and user clicks logout. With a slow network, we could have a race condition, when private data would arrive after user logged out. Aborting a pending request in the case like this would prevent such a disaster.