-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve HttpRequests
#1741
base: main
Are you sure you want to change the base?
Improve HttpRequests
#1741
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #1741 +/- ##
==========================================
+ Coverage 98.21% 98.44% +0.23%
==========================================
Files 17 17
Lines 1565 1606 +41
Branches 333 343 +10
==========================================
+ Hits 1537 1581 +44
+ Misses 28 25 -3 ☔ View full report in Codecov by Sentry. |
src/clients/client.ts
Outdated
body: params, | ||
})) as EnqueuedTaskObject; | ||
|
||
return new EnqueuedTask(taks); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bug: previously this did not return EnqueuedTask
, but rather EnqueuedTaskObject
tests/client.test.ts
Outdated
test(`${permission} key: Create client with custom headers (object)`, async () => { | ||
const key = await getKey(permission); | ||
const client = new MeiliSearch({ | ||
...config, | ||
apiKey: key, | ||
requestInit: { | ||
headers: { | ||
"Hello-There!": "General Kenobi", | ||
}, | ||
}, | ||
}, | ||
}); | ||
|
||
assert.isTrue(await client.isHealthy()); | ||
|
||
assert.isDefined(fetchSpy.mock.lastCall); | ||
const [, requestInit] = fetchSpy.mock.lastCall!; | ||
|
||
assert.isDefined(requestInit?.headers); | ||
assert.instanceOf(requestInit!.headers, Headers); | ||
assert.strictEqual( | ||
(requestInit!.headers! as Headers).get("Hello-There!"), | ||
"General Kenobi", | ||
); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because headers are internal implementation details, to check them we have to spy on fetch
now.
src/indexes.ts
Outdated
async deleteDocument(documentId: string | number): Promise<EnqueuedTask> { | ||
const url = `indexes/${this.uid}/documents/${documentId}`; | ||
const task = await this.httpRequest.delete<EnqueuedTask>(url); | ||
|
||
task.enqueuedAt = new Date(task.enqueuedAt); | ||
const task = (await this.httpRequest.delete({ | ||
relativeURL: `indexes/${this.uid}/documents/${documentId}`, | ||
})) as EnqueuedTaskObject; | ||
|
||
return task; | ||
return new EnqueuedTask(task); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bug: previously this did not return EnqueuedTask
src/indexes.ts
Outdated
async updateSettings(settings: Settings): Promise<EnqueuedTask> { | ||
const url = `indexes/${this.uid}/settings`; | ||
const task = await this.httpRequest.patch(url, settings); | ||
const task = (await this.httpRequest.patch({ | ||
relativeURL: `indexes/${this.uid}/settings`, | ||
body: settings, | ||
})) as EnqueuedTaskObject; | ||
|
||
task.enqueued = new Date(task.enqueuedAt); | ||
|
||
return task; | ||
return new EnqueuedTask(task); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bug: previously this did not return EnqueuedTask
, I'm not going to mark the rest, there are more
…-js into improve-http-request
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @flevi29, thanks for the great work 🙌
I would love to merge this too before the new release!I have a few questions:
Generic methods types
Any reason to switch from method<Type>()
to method() as Type
?
One example is in indexes.ts
: await this.httpRequest.get(...) as IndexObject;
, but there are other occurrences of this.
The former approach seems to provide a better DX.
Renaming config
to extraRequestInit
I'm all for renaming it in variables and types used internally to make the code base more self-explanatory. But I'm not sure about changing the user-facing field names.
I feel like config
/ requestConfig
are more familiar field names for configuring the underlying HTTP client/request.
Plus, changing them would be a breaking change, right?
@@ -1435,10 +1437,66 @@ describe.each([ | |||
try { | |||
await client.health(); | |||
} catch (e: any) { | |||
expect(e.cause.message).toEqual("Error: Request Timed Out"); | |||
expect(e.cause.message).toEqual("request timed out after 1ms"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's keep it closer to the original formatting:
expect(e.cause.message).toEqual("request timed out after 1ms"); | |
expect(e.cause.message).toEqual("Error: Request timed out after 1ms"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's just the message part. Error, when stringified, already prefixes the "Error: ", where "Error" is the property name
.
> console.log(new Error("request timed out"))
Error: request timed out
at REPL1:1:13
If I'd add that into the message it would look like so when logged:
> console.log(new Error("Error: request timed out"))
Error: Error: request timed out
at REPL2:1:13
Is this what you're referring to?
expect(e.name).toEqual("MeiliSearchRequestError"); | ||
} | ||
}); | ||
|
||
test(`${permission} key: search should be aborted on already abort signal`, async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the name of this test. Can you explain, or rephrase it, please?
The idea was that when we are calling an external web API, the shape of the response cannot be guaranteed, so we're casting to be explicit about this fact. But you are right, it is an overkill, I'm moving the casting part to
I felt like "RequestInit" is more explicit, because that's literally what it's named and what we're using and allowing via types and it is the standard at this point, while It is named "extra", because we're applying 3 layers of Also there's an open issue about adding this extra config to all of the methods #1476 |
Pull Request
Sorry for the huge PR, but
HttpRequests
is core, and is used everywhere.What does this PR do?
EnqueuedTaskObject
s not being converted toEnqueuedTask
Caution
BREAKING: From now on only some methods are public on
HttpRequests
(get
,post
,put
,patch
,delete
), the rest of the properties and methods are internal implementation details, and are not meant to be directly accessed.PR checklist
Please check if your PR fulfills the following requirements:
Thank you so much for contributing to Meilisearch!