Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 23 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -342,11 +342,30 @@ const mercurius = fp(async function (app, opts) {
}
}

function serialize (query) {
if (query.info) {
return stringify({ obj: query.obj, params: query.params })
/**
* Custom serialization function for batching GraphQL loaders.
*
* This ensures that similar queries (e.g. same obj.id and language) can be grouped
* into a single batched call.
*
* We use `obj.id` when available because:
* - It's a common convention (used in most GraphQL schemas)
* - It's stable and unique across objects
* - It's much faster than serializing the entire object
*
* If `obj.id` is not available, we fall back to a full serialization of both
* `obj` and `params` to ensure uniqueness (at the cost of performance).
*
* This improves performance for large GraphQL queries that call the same
* field resolver many times (e.g. N+1 problems), by allowing batching to work properly.
*/
function serialize ({ obj, params }) {
if (obj?.id !== undefined) {
const lang = params?.lang ?? null
return JSON.stringify([obj.id, lang])
}
return query

return stringify({ obj, params })
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is generic enough to be included in the library. How about you add a a way to include a custom serializer for the loader instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. I found a better way to handle it. Also i will add some tests for it. After that if you like it can pr docs for that too. I will publish it soon


const resolvers = {}
Expand Down
66 changes: 33 additions & 33 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,48 +28,48 @@
"graphql": "^16.0.0"
},
"devDependencies": {
"@graphql-tools/merge": "^9.0.0",
"@graphql-tools/schema": "^10.0.0",
"@graphql-tools/utils": "^10.0.0",
"@graphql-tools/merge": "^9.0.24",
"@graphql-tools/schema": "^10.0.23",
"@graphql-tools/utils": "^10.8.6",
"@sinonjs/fake-timers": "^14.0.0",
"@types/isomorphic-form-data": "^2.0.0",
"@types/node": "^22.0.0",
"@types/ws": "^8.2.0",
"@types/isomorphic-form-data": "^2.0.4",
"@types/node": "^22.14.0",
"@types/ws": "^8.18.1",
"autocannon": "^8.0.0",
"concurrently": "^9.0.0",
"docsify-cli": "^4.4.3",
"eslint": "^9.9.1",
"fastify": "^5.0.0",
"graphql": "^16.0.0",
"concurrently": "^9.1.2",
"docsify-cli": "^4.4.4",
"eslint": "^9.24.0",
"fastify": "^5.2.2",
"graphql": "^16.10.0",
"graphql-tag": "^2.12.6",
"graphql-ws": "^6.0.1",
"neostandard": "^0.12.0",
"graphql-ws": "^6.0.4",
"neostandard": "^0.12.1",
"pre-commit": "^1.2.2",
"proxyquire": "^2.1.3",
"semver": "^7.5.0",
"semver": "^7.7.1",
"sinon": "^20.0.0",
"split2": "^4.0.0",
"tap": "^21.0.0",
"tsd": "^0.31.0",
"typescript": "^5.0.2",
"undici": "^7.0.0",
"wait-on": "^8.0.0"
"split2": "^4.2.0",
"tap": "^21.1.0",
"tsd": "^0.32.0",
"typescript": "^5.8.3",
"undici": "^7.7.0",
"wait-on": "^8.0.3"
},
"dependencies": {
"@fastify/error": "^4.0.0",
"@fastify/static": "^8.0.0",
"@fastify/websocket": "^11.0.0",
"fastify-plugin": "^5.0.0",
"@fastify/error": "^4.1.0",
"@fastify/static": "^8.1.1",
"@fastify/websocket": "^11.0.2",
"fastify-plugin": "^5.0.1",
"graphql-jit": "0.8.7",
"mqemitter": "^6.0.0",
"p-map": "^4.0.0",
"quick-lru": "^7.0.0",
"readable-stream": "^4.0.0",
"safe-stable-stringify": "^2.3.0",
"secure-json-parse": "^3.0.0",
"single-user-cache": "^1.0.0",
"tiny-lru": "^11.0.0",
"ws": "^8.2.2"
"mqemitter": "^6.0.2",
"p-map": "^7.0.3",
"quick-lru": "^7.0.1",
"readable-stream": "^4.7.0",
"safe-stable-stringify": "^2.5.0",
"secure-json-parse": "^4.0.0",
"single-user-cache": "^1.0.1",
"tiny-lru": "^11.2.11",
"ws": "^8.18.1"
},
"tsd": {
"directory": "test/types"
Expand Down
4 changes: 2 additions & 2 deletions static/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ function render () {

function importDependencies () {
const link = document.createElement('link')
link.href = 'https://unpkg.com/graphiql@3.7.1/graphiql.min.css'
link.href = 'https://unpkg.com/graphiql@3.8.3/graphiql.min.css'
link.type = 'text/css'
link.rel = 'stylesheet'
link.media = 'screen,print'
Expand All @@ -167,7 +167,7 @@ function importDependencies () {
return importer.urls([
'https://unpkg.com/[email protected]/umd/react.production.min.js',
'https://unpkg.com/[email protected]/umd/react-dom.production.min.js',
'https://unpkg.com/graphiql@3.7.1/graphiql.min.js'
'https://unpkg.com/graphiql@3.8.3/graphiql.min.js'
]).then(function () {
const pluginUrls = window.GRAPHIQL_PLUGIN_LIST
.map(plugin => window[`GRAPIHQL_PLUGIN_${plugin.toUpperCase()}`].umdUrl)
Expand Down
6 changes: 3 additions & 3 deletions static/sw.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

self.addEventListener('install', function (e) {
e.waitUntil(
caches.open('graphiql-v3.7.1').then(function (cache) {
caches.open('graphiql-v3.8.3').then(function (cache) {
return cache.addAll([
'./main.js',
'https://unpkg.com/graphiql@3.7.1/graphiql.css',
'https://unpkg.com/graphiql@3.8.3/graphiql.css',
'https://unpkg.com/[email protected]/umd/react.production.min.js',
'https://unpkg.com/[email protected]/umd/react-dom.production.min.js',
'https://unpkg.com/graphiql@3.7.1/graphiql.min.js'
'https://unpkg.com/graphiql@3.8.3/graphiql.min.js'
])
})
)
Expand Down
Loading