Skip to content

Commit bf5fb10

Browse files
committed
sort query parameters
1 parent 181ccd9 commit bf5fb10

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

src/http-data-source.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ export abstract class HTTPDataSource<TContext = any> extends DataSource {
109109
}
110110
}
111111
}
112+
113+
// avoid cache fragmentation when the query order is not guaranteed
114+
params.sort()
115+
112116
return params.toString()
113117
}
114118

@@ -342,7 +346,7 @@ export abstract class HTTPDataSource<TContext = any> extends DataSource {
342346
}
343347

344348
private async request<TResult = unknown>(request: Request): Promise<Response<TResult>> {
345-
if (Object.keys(request?.query).length > 0) {
349+
if (Object.keys(request.query).length > 0) {
346350
request.path = request.path + '?' + this.buildQueryString(request.query)
347351
}
348352

test/http-data-source.test.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,49 @@ test('Should be able to define a custom cache key for request memoization', asyn
551551
t.deepEqual(response.body, wanted)
552552
})
553553

554+
test('Should correctly calculate and sort query parameters', async (t) => {
555+
t.plan(3)
556+
557+
const path = '/'
558+
559+
const wanted = { name: 'foo' }
560+
561+
const server = http.createServer((req, res) => {
562+
t.is(req.method, 'GET')
563+
t.is(req.url, '/?a=1&b=2&z=z')
564+
res.writeHead(200, {
565+
'content-type': 'application/json',
566+
})
567+
res.write(JSON.stringify(wanted))
568+
res.end()
569+
res.socket?.unref()
570+
})
571+
572+
t.teardown(server.close.bind(server))
573+
574+
server.listen()
575+
576+
const baseURL = `http://localhost:${(server.address() as AddressInfo)?.port}`
577+
578+
const dataSource = new (class extends HTTPDataSource {
579+
constructor() {
580+
super(baseURL)
581+
}
582+
getFoo() {
583+
return this.get(path, {
584+
query: {
585+
b: 2,
586+
a: 1,
587+
z: 'z',
588+
},
589+
})
590+
}
591+
})()
592+
593+
let response = await dataSource.getFoo()
594+
t.deepEqual(response.body, wanted)
595+
})
596+
554597
test('Should call onError on request error', async (t) => {
555598
t.plan(11)
556599

@@ -1394,4 +1437,4 @@ test('Should be able to pass custom Undici Pool', async (t) => {
13941437
const response = await dataSource.getFoo()
13951438

13961439
t.deepEqual(response.body, wanted)
1397-
})
1440+
})

0 commit comments

Comments
 (0)