apollo-ios
apollo-ios copied to clipboard
Support query batching
We've come across a situation where query (and mutation) batching would be very useful. I noticed that this was an issue in the Android project but not in the iOS one so I wanted to add a reference here.
https://github.com/apollographql/apollo-android/issues/513
Thanks! Once https://github.com/apollographql/apollo-ios/pull/186 lands that should make it easier to add support for query batching.
Out of curiosity, what is your use case? Especially with HTTP/2, query batching doesn't seem to have that many performance benefits and may actually degrade performance.
We'd like to use it to pass n-mutations in a set order. Our specific use case is the removal of n items in a hierarchical list (where you can't remove the parent before the children are removed) in one go. An example for a mutation like this could be:
mutation {
child1: remove(id: "2"){ id }
child2: remove(id: "3"){ id }
child3: remove(id: "4"){ id }
parent: remove(id: "1"){ id }
}
We didn't want to go the route of having the removal of the parent take the children so we can catch potentially erroneous behavior and ask the user what they want to do (i.e. move the children to another parent, or actually remove all the children).
Ah, I see. Query batching as currently implemented in Apollo Server would work for this I think, but ordering isn't actually guaranteed (unlike putting multiple mutations in a single operation, as you've done above).
Would something like remove(id: ..., cascadeToChildren: true) or a batch removeAll(ids: ) be an alternative?
I was considering the removeAll(ids: [ID]!) route. The only downside is we lose the nice error tracing that GraphQL gives us. i.e. If ID number 3 fails, then the multiple mutations in a single operation would give us a trace to that failed mutation and the client would know to deal with just that failed mutation. With removeAll, a custom error format would be required to give us that kind of functionality.
I also think I might not quite understand how query batching works in Apollo Server. Does the batching simply let you send multiple operations in a row? If that's the case then you're right it's probably not what I'm looking for. Instead what I was describing is a sort of mutateInSequence method that takes a list of mutations and merges them into that un-named operation and runs that. It'd be really cool but also sounds nasty to implement 😄
Depending on the underlying service or datastore, a single mutation would have the benefit that you can run it in a transaction and have everything automatically rolled back when a removal fails. But you're right, there is no built-in way to include an error per id. Perhaps you could define a custom result object if you really need it. Something like:
removeAll(ids: $ids) {
removedItems {
id
}
}
Query batching in Apollo Server is indeed just a way to send multiple operations in one request. Currently operations are executed in sequence I believe, but it is not guaranteed and we may want to execute them in parallel.
Hi @martijnwalraven, are there any plans on adding support for Transport-level query batching? Our app can do multiple queries at once and then it would be useful if those could be send to the server in 1 request instead of multiple request.
Hey guys,
Do we have any plans on supporting query batching? Is there a doc we can refer to about the roadmap of Apollo-iOS?
Marking this as an enhancement - I don't have a timeline for this but it does seem like a useful thing to add support for to reduce the number of round-trips necessary if possible.
@thonydam Right now we don't have a roadmap doc, but I'll be working on that at some point in the next few months once I get the open issues a bit more under control.
@designatednerd Thanks for the update and your work! Glad to see that this repo will get more love!
Any updates on this topic? (This topic is mixed with another and followed up on https://github.com/apollographql/apollo-ios/issues/884. Not sure what the current status is though).
I'm going to look at adding both of these as we update the networking stack but I do not have an ETA.
@designatednerd - can this issue be re-examined for viability following the network stack rearchitecture?
Has there been any update to enable query batching for iOS? My team is hoping to use batching for web and android requests but we're not sure this is the right path since it isn't currently supported for apollo client in iOS.
@danwkennedy @designatednerd @martijnwalraven
Hi @daniel-r-hartman - Our team won't be able to get to this until v2.0 where networking will be the focus of that major version. We are always happy to work with community member contributions though; reviewing and guiding where we can.
Thanks for the reply @calvincestari. Is there any timeline or estimate of when this feature might be available?
My team is currently evaluating working on a custom solution for batching, vs contributing to this project, vs non-batching solutions.
There is no estimated timeline for v2.0 yet. We're still working on v1.0 which is focussed on code generation. If I were to guess at a timeline right now I'd say second half of 2022.
Assume this is still pending? Thanks!
Assume this is still pending? Thanks!
We haven't started on 2.0 yet. This will be included in that work.
I am currently using apollo client 1.2.0 ios version, but query batching is not available though. Could you please update on this
Hi @ArunVicky001. Query batching is still not a native feature of Apollo iOS but it is possible and you will need to code your own request body creator to get it working.
0.51.1 included a change to expose the request body creation. This is the hook for you to use and build a custom request body that would batch together the operations. You'll also probably need a custom response interceptor to parse the response if it's going to include more than a single data object in the body.
@calvincestari which means we need to make change in the query itself right?
You need to change the request that gets sent to the server. You cannot change the GraphQL query to enable batching.
Got it,
on other hand can we implement like this?
import Apollo
let apolloClient = ApolloClient(url: URL(string: "https://api.graphql.org/")!)
let query1 = """
query {
viewer {
name
}
}
"""
let query2 = """
query {
repository(owner: "apollographql", name: "apollo-client") {
name
}
}
"""
let dispatchGroup = DispatchGroup()
var viewerName: String?
var repositoryName: String?
dispatchGroup.enter()
apolloClient.fetch(query: query1) { result in
defer { dispatchGroup.leave() }
switch result {
case .success(let graphQLResult):
viewerName = graphQLResult.data?.viewer?.name
case .failure(let error):
print("Error querying viewer: \(error)")
}
}
dispatchGroup.enter()
apolloClient.fetch(query: query2) { result in
defer { dispatchGroup.leave() }
switch result {
case .success(let graphQLResult):
repositoryName = graphQLResult.data?.repository?.name
case .failure(let error):
print("Error querying repository: \(error)")
}
}
dispatchGroup.notify(queue: .main) {
if let name = viewerName {
print("Viewer Name: \(name)")
}
if let repoName = repositoryName {
print("Repository Name: \(repoName)")
}
}
Yes, you could do that. It's slightly more complicated for the client but the end result of time-to-wait for the user should be the same as query batching on the server because the server wouldn't combine the responses, i.e.: the client would still have to parse two data responses.
The best eventual solution for this is probably to use @defer. We're working on it now for Apollo iOS but it would also require changes to your queries to combine the fields you want immediately and the ones that can be deferred.
@ArunVicky001 I'm going to close this issue now as there isn't anything actionable for our team.
Oh wait, this is a long-standing issue we're keeping around for the 2.0 work. My mistake.
What is the update? Any luck for query batching
@ArunVicky001 This work is going to be included in the work for version 2.0 which doesn't currently have a date however you can follow our roadmap which is updated consistently to keep track of upcoming and planned work.
@BobaFetters Thanks for your response..