-
-
Notifications
You must be signed in to change notification settings - Fork 62
Allow middleware to be async, deprecate createAsyncMiddleware #81
base: main
Are you sure you want to change the base?
Conversation
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.
This generally seems promising! You really had me there with the title 😅 I thought you were getting rid of async middleware, but no, you're making all middleware optionally async.
I'd recommend leaving createAsyncMiddleware
around in this PR and marking it as deprecated instead, to make migrating away from createAsyncMiddleware
easier. We can remove it completely later on.
i think bumping major here is sufficient, others will still pull in the older version with the middleware util |
hmm, i actually dont like this. |
create async middleware currently allows you to |
aca7998
to
1d9f07c
Compare
The main reason for removing I decided to keep |
* Handle errors fro masync middleware function rejections * Update readme * Update JsonRpcMiddleware type * Prevent promise resolution function from being called twice
2cdcf45
to
378a820
Compare
We actually need this to please the linter. This reverts commit 36d91ad.
@@ -19,7 +19,7 @@ type ScaffoldMiddlewareHandler< | |||
export function createScaffoldMiddleware(handlers: { | |||
[methodName: string]: ScaffoldMiddlewareHandler<JsonRpcParams, Json>; | |||
}): JsonRpcMiddleware<JsonRpcParams, Json> { | |||
return (req, res, next, end) => { | |||
return async (req, res, next, end) => { |
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.
The linter is asking for this, because middleware can now be async. We could create sync and async middleware types, not sure if it's worth it.
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.
This seems fine. Make all the things 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.
Hi @rekmarks, I know you've been waiting for movement on this. I've had this on my list for a while and finally took the time to review this. I definitely learned some things while reviewing this, like how async middleware resolve the request via a callback passed to next
, and that those callbacks are processed in reverse order when all middleware has been processed. I haven't 100% fully grokked how that works, but it does seem purely based on how it's used internally that next
is less of a necessity and more of an implementation detail, so I'm glad that we're removing it to make things simpler.
Anyway, I really have only one suggestion here, but I understand your changes enough to say that they're good. I will monitor this PR this week so we can finally merge it.
returnHandlers.push(returnHandler); | ||
} | ||
|
||
// False indicates that the request should not end |
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.
Thought for another PR: I'm curious whether it would make more sense to make this an object rather than an array so we can make this self-documenting:
return resolve({ error: null, isComplete: false });
|
||
try { | ||
await middleware(request, response, next, end); | ||
} catch (error: any) { |
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.
Nit: Does it make more sense to use unknown
rather than any
here?
* | ||
* The return handler will always be called. Its resolution of the promise | ||
* enables the control flow described above. | ||
* | ||
* @deprecated As of version 7.1.0, middleware functions can be asnync. This |
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.
Typo
* @deprecated As of version 7.1.0, middleware functions can be asnync. This | |
* @deprecated As of version 7.1.0, middleware functions can be async. This |
} | ||
returnHandlers.push(returnHandler); | ||
} | ||
let resolve: (value: [unknown, boolean]) => void; |
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.
Ah, I see, the reason why we have to do this now is because the function that the Promise constructor takes can't itself be async
? Good solution.
} else { | ||
innerEnd(null); | ||
} | ||
} catch (error: any) { |
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.
Nit:
} catch (error: any) { | |
} catch (error: unknown) { |
@@ -19,7 +19,7 @@ type ScaffoldMiddlewareHandler< | |||
export function createScaffoldMiddleware(handlers: { | |||
[methodName: string]: ScaffoldMiddlewareHandler<JsonRpcParams, Json>; | |||
}): JsonRpcMiddleware<JsonRpcParams, Json> { | |||
return (req, res, next, end) => { | |||
return async (req, res, next, end) => { |
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.
This seems fine. Make all the things async!
This library has now been migrated into the core monorepo. This PR has been locked and this repo will be archived shortly. Going forward, releases of this library will only include changes made in the core repo.
|
This PR lets any middleware function be async, and deprecates
createAsyncMiddleware
. The readme has been updated.Previously, we did not handle rejections of plain,
async
middleware functions.createAsyncMiddleware
was created in part to solve this problem. This PR introduces a simple refactor of#runMiddleware
to handle rejections byasync
middleware functions.It accomplishes this using a deferred promise, which was one of the techniques used to implement
createAsyncMiddleware
. Meanwhile,createAsyncMiddleware
has been updated in order to retain backwards compatibility.This change should be fully backwards-compatible.