Batch multiple queries in a single API call and drop in queryParams using the structure above.

61 replies
Last updated: Mar 24, 2022
Is there any ability to batch multiple queries into a single api call?
AI Update

Yes! Sanity supports batching multiple operations, but it depends on whether you're doing writes (mutations) or reads (queries).

For mutations (writes): Sanity has built-in support for batching through transactions. Transactions allow you to bundle multiple creates, updates, and deletes into a single atomic API call where either all changes succeed or all fail together:

import {client} from './sanityClient'

const transaction = client.transaction()
  .create({_type: 'post', title: 'First post'})
  .patch('doc-id-123', p => p.set({title: 'Updated title'}))
  .delete('doc-id-456')

await transaction.commit()

This sends all three operations in one HTTP request with ACID-compliant guarantees.

For queries (reads): Sanity doesn't currently offer a native batch query API that lets you execute multiple separate GROQ queries in a single HTTP request. Each client.fetch() call is a separate API request.

However, you have these alternatives:

  1. Combine queries using GROQ projections - Structure a single query to fetch multiple datasets:
const data = await client.fetch(`{
  "posts": *[_type == "post"],
  "authors": *[_type == "author"],
  "categories": *[_type == "category"]
}`)
  1. Use Sanity Functions - Create a serverless function that executes multiple queries server-side and returns combined results, reducing round trips from your client.

  2. Leverage GROQ joins and references - Fetch related data in one query using references and projections rather than multiple separate queries.

So while there's no "batch query API" like some platforms offer, the transaction API handles mutation batching well, and GROQ's flexibility lets you consolidate most read operations into efficient single queries.

{"query1":*[_type == "post"]{title, content}, "query2":*[_type=="category"]{title}}
oh nice. Thanks
user Q
!
šŸ™‚
actually follow up question, what would be the proper way to drop in queryParams using the structure above?
What do you mean?
i think i got it, was referring to something like this
{
   "query1":*[_type == "post" && slug == $post_slug]{title, content}, 
   "query2":*[_type=="category" && slug == $cat_slug]{title}
}
I think that should work, make sure you serialize it before sending
.fetch({
   "query1":*[_type == "post" && slug == $post_slug]{title, content}, 
   "query2":*[_type=="category" && slug == $cat_slug]{title}
},{ $post_slug:'foo', $cat_slug:'bar'});

I’m thinking that should work right? ā˜ļø
const res = fetch ('<https://foobar.api.sanity.io/v2021-10-21/data/query/production?query=>' + encodeURIComponent('QUERY HERE'))
this is essentially how I do it
Need to encode the query as a URIcomponent
Ok cool, thanks a lot appreciate the thoughts on this
Np. Basically you need to find your API address in the studio, then append your URI encoded query to the end of it.
This is a smart way to do it, just ran a test and it looks like you can’t do multiple queries like this using the sanity client
What do you mean?

{"sidebar":*[_type == "sidebar"]{title, content, "fileURL":pdf.asset->url},"contact":*[_type=="contact"][0],"pages":*[_type=="pages"]{title, "slug":slug.current},"settings":*[_type=="siteSettings"][0]{...,"logos":{"primary":logo1.asset->url, "secondary":logo2.asset->url},sponsors[]{title,"url":logo.asset->url}}}
^ This works fine in the sanity client
oh i see, you’re using projections… from your prior example was doing it a bit different
like taking a deep query and dropping into an object
{ myBigQuery: *[…]{ a bunch of stuff}, myOtherBigQuery: etc… }
All makes sense — sorry for the confusion
No problem šŸ™‚
Coming from the GQL world, GROQ is quite impressive
I remember the gql wordpress days...🤮
This is my first go on a real project with Sanity and honestly I can’t imagine ever using another CMS after this
The level of control and customization is unmatched
It's incredible how intuitive it can be
But it also means I need to learn react, so...lol
Yep
Thankfully, I know the react world like the back of my hand so this has been smooth sailing
next.js + sanity = šŸ˜
Hah, lucky you. I should learn react anyways so it's nbd. Sanity + Svelte has been like walking on water from a dev experience standpoint
ooh yeah I bet. Svelte is awesome, I’ve played around with it a bit
Just curious, do you do any freelance/contract work?
Have you used gatsby? That one looks intriguing
Yeah I'm a freelancer actually
Looks like your mountain time?
yeah
Nice, well I have a web dev shop in LA and we are on the hunt for some solid frontend devs as the project load has been growing
If you’re interested, shoot me a portfolio site and/or a linkedin profile so we can connect
We do a lot of entertainment stuff, and starting to get into brand work, and are itching to start doing some Web3 stuff
Anyhoo, sorry to get off topic just wanted to throw that out there
If you’re interested feel free to reach out to miked@droplab.com
Ooh thats cool, sounds like a fun set of clients
Yeah the entertainment stuff is fun for sure
I'm just making some changes to my business site, once I get it up I'll send you a link and stuff
šŸ‘
Are you in the US or CA ?
I'm curious, what is that cursor effect on the home page? three.js?Canada
That’s a shader we wrote, via three.js
Site is SUPER old
We’ve been so busy, haven’t had time to update — been trying for a couple years now lol
Good problem to have I guess
Hah, yes, good problem.
Are you KinLabs ?
thats me!
Cool, pinged you on LinkedIn
Definitely hit me up when you have site sorted out and/or wanna chat about some freelance opportunities
Sounds good, I'm definitely interested.
šŸ‘

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?