-
Notifications
You must be signed in to change notification settings - Fork 393
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
Allows the use of supplied Router
object to ExpressReceiver
#870
Conversation
Codecov Report
@@ Coverage Diff @@
## main #870 +/- ##
==========================================
- Coverage 66.08% 66.05% -0.03%
==========================================
Files 13 13
Lines 1200 1205 +5
Branches 353 359 +6
==========================================
+ Hits 793 796 +3
- Misses 338 339 +1
- Partials 69 70 +1
Continue to review full report at Codecov.
|
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'd be lying if I said setting app to undefined
doesn't make me uncomfortable. I could see this type change causing some confusion for some developers.
To me, it seems you just want to take advantage of the receivers ability to setup routes (like slack/events
) and use the built in middleware.
Passing in your own router does really make ExpressReceiver
pretty useless.
You could plug your bolt app into existing Express apps already via something like #212 (comment). What benefit would this approach have over the one in the comment?
src/receivers/ExpressReceiver.ts
Outdated
@@ -33,6 +34,7 @@ export interface ExpressReceiverOptions { | |||
installationStore?: InstallProviderOptions['installationStore']; // default MemoryInstallationStore | |||
scopes?: InstallURLOptions['scopes']; | |||
installerOptions?: InstallerOptions; | |||
router?: core.Router; |
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.
IRouter
should be a more relevant type for this argument as express.Application
instance inherits the type not core.Router
.
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.
ahh gotcha, thanks! Tbh I didn't know IRouter
even existed 😅
src/receivers/ExpressReceiver.ts
Outdated
): Promise<Server | HTTPSServer> { | ||
): Promise<Server | HTTPSServer | void> { | ||
if (!this.app) { | ||
return Promise.resolve(); |
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.
How about adding logs here? For instance,
this.logger.info('As the Express app instance is not managed by this receiver, #start() method does nothing.');
or something like that. If it's fine, we can do the same for the stop() method
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.
Ya that seems like a good idea to me!
Thanks for working on this! For your information, I've created my suggestion branch, which is based on your branch: seratch@b11b04b As I did in the branch, adding a new example app for this use case may be a good addition. What do you think? @stevengill |
Ah, sorry - I overlooked @stevengill's above comment. So, is one possible solution to enable passing Am I missing something? |
Passing |
Hey @stevengill @seratch sorry for the delay!
This is interesting! But in |
@rr-codes I may not understand your concern about the start method yet. When you directly use |
Hey @rr-codes I agree with Kaz, I don't think the developer will have to call |
@seratch @stevengill oh true ok ya I was confusing myself. So yup I agree with both of you! |
also @stevengill you mentioned this alternative; however, |
This is correct. By the way, are you going to work on this one very soon? No rush at all but I'm thinking about the release timing of v3.4. If we need more time for this PR, it's totally fine to move this one to v3.5 milestone. |
@seratch hey, so ya I've been working on this, and I've been thinking about the possibilities of making the receiver act as an express middleware, so like So I've just been trying to figure out how to / if its even possible to accomplish this. What do you think? |
@rr-codes If I understand correctly, it should be possible to implement a Receiver as an Express middleware and I agree that's a clearer design. However, the receiver can be a bit different thing from the current For these reasons, my suggestion here is to continue exploring a greater design for a while and decide where to go once we've figured it out. Let me move this from v3.4 scopes from future versions (v3.5 as a tentative plan). Thanks for your efforts here! |
@seratch thoughts on my most recent commit? I extracted all the middleware logic into its own class, which can be used standalone with any receiver. I really like this approach as it provides much more flexibility, without affecting |
@rr-codes To safely expose the main Going back to the original topic you raised at #868, the latest revision is no longer a solution for improving I also think that the built-in |
As #1084 resolves the issue #868 in a simpler way, let us close this pull request now. I am still thinking that some of the changes here can be great addition. If we want to continue for other improvement purposes, we are happy to do so. Thanks for taking the time to make these change suggestions here! |
Summary
The goal of this PR is to allow for using a custom express router by an express app to be used for
ExpressReceiver
instead of having the receiver itself own the express app and router. This enhancement also relates to #212 and the upward modularity philosophy.From a software design perspective, this isn't the most sensical design ever, as it essentially defeats the purpose of the
Receiver
interface more or less, but it gets the job done and is usable without requiring a major refactor to Bolt.In this implementation, if a
Router
is supplied to the constructor, no express app or router is created. As a result, there is nothing forstart
orstop
to do, so both are no-op in this case and return aPromise
which resolves to void.Closes #868 .
Requirements (place an
x
in each[ ]
)