-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Add app
and server
to server setupFn
#1017
Conversation
@@ -5,7 +5,8 @@ let someResource = undefined | |||
|
|||
export const getSomeResource = () => someResource | |||
|
|||
const setup = async () => { | |||
const setup = async (app, _server) => { |
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 would recommend adding a type for the ServerSetupFn
like:
type ServerSetupFn = (context: ServerSetupFnContext) => void;
type ServerSetupFnContext = {
app: express.Application,
server: http.Server,
};
which the user can import like import { ServerSetupFnContext } from '@wasp/types';
or similar.
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.
Yep, can do. 👍🏻 This is just a WIP skeleton at the moment but will beef it out tomorrow some more before tagging for reviews.
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.
Added some types, thanks!
export type Application = express.Application | ||
|
||
export type Server = http.Server |
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.
Thoughts on exporting type aliases like these? I would like people to be able to pass around/use the components of ServerSetupFnContext
and still have proper typing, but without having to import the actual express
/node
imports themselves. I think it makes it nice they can get it all from the same import path, but curious on the TS expert pros/cons here. The downside is they will still need to know it is actually an express.Application
if they want to use it with other libraries, look up docs, etc. but I hope that is an ok use for aliases? Thanks!
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.
For example, see function addCustomRoute(app: Application)
in serverSetup.ts
.
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 like the reexport in our context, so users can import from @wasp/types
👍
I would maybe write it a bit differently:
import { Application } from 'express';
import { Server } from 'http';
export type ServerSetupFn = (context: ServerSetupFnContext) => Promise<void>
export type ServerSetupFnContext = {
app: Application,
server: Server,
}
export { Application } from 'express';
export { Server } from 'http';
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.
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.
Sounds good, thanks @infomiho for a better convention to use!
{=# doesServerSetupFnExist =} | ||
await {= serverSetupJsFnIdentifier =}() | ||
const serverSetupFnContext: ServerSetupFnContext = { app, server } |
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.
@shayneczyzewski Why are we exposing the server
object? I'm not sure for which use case it's needed
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.
Many websocket libraries wrap the server. For example: https://socket.io/get-started/chat#integrating-socketio That was one main use case I was hoping to cover here as well (and that won't be covered by the api
DSL next step).
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.
Makes sense, I though that socket.io
didn't need the server 🤦♂️
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.
When I was doing this for an experiment, I did it as described here: https://discord.com/channels/686873244791210014/920312576133443634/1070052697572638870 -> so I passed app
to setupFn, but I didn't move the server creation above it and then pass it.
I think it is cool that you did, that gives people more stuff to work with!
But it does change behavior a bit -> before, setupFn
was allowing you to do stuff before server
is created. Now, it allows you to set up stuff after server is created. I have no idea if we loose anything with that? Is there a use case where it might be important to do something before server
is created from app
? If we are not sure now, that is ok, we can just go with this and if we learn there is use case for it, we can add another function called preSetupFn
or smth, that will be called just before the server.
One thing I thought was important was to add routes to app
before the server(app)
is called, but I guess I was wrong because I am sure you tested this and it works, even though you add stuff to app
after the server(app)
is called. Interesting. But does it work because it should, or by accident?
Maybe we can get some answers here: https://nodejs.org/api/http.html#class-httpserver .
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.
Good question @Martinsos - I don't think there is any technical reason why we have to keep it after, but you are right it does change the previous implied semantics a bit from user-level docs (which I massaged to say "before the server starts accepting requests"). But I don't think there is any actual technical impact in doing this swap. The custom route I setup in the setupFn
still worked even when createServer
happened before. I am not aware of any other potential impacts of this.
I believe createServer
is just registering a request handler callback (of which an Express instance itself is). That callback should be using things internally that can be set either before or after that registration (i.e. it shouldn't even know it was registered to me). But I will do more testing and digging to be 100% sure (including doing a Socket.IO test too).
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.
Sounds good @shayneczyzewski !
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.
It's not pretty (we have to specify the client/server URLs since different domains) but you can get Socket.IO up and running with access to server
: https://gist.github.com/shayneczyzewski/165b4266d77a2a75454f605dd55b5db7
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.
@shayneczyzewski this is it from me, I will let @sodic or @infomiho handle the TS side of this!
{=# doesServerSetupFnExist =} | ||
await {= serverSetupJsFnIdentifier =}() | ||
const serverSetupFnContext: ServerSetupFnContext = { app, server } |
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.
When I was doing this for an experiment, I did it as described here: https://discord.com/channels/686873244791210014/920312576133443634/1070052697572638870 -> so I passed app
to setupFn, but I didn't move the server creation above it and then pass it.
I think it is cool that you did, that gives people more stuff to work with!
But it does change behavior a bit -> before, setupFn
was allowing you to do stuff before server
is created. Now, it allows you to set up stuff after server is created. I have no idea if we loose anything with that? Is there a use case where it might be important to do something before server
is created from app
? If we are not sure now, that is ok, we can just go with this and if we learn there is use case for it, we can add another function called preSetupFn
or smth, that will be called just before the server.
One thing I thought was important was to add routes to app
before the server(app)
is called, but I guess I was wrong because I am sure you tested this and it works, even though you add stuff to app
after the server(app)
is called. Interesting. But does it work because it should, or by accident?
Maybe we can get some answers here: https://nodejs.org/api/http.html#class-httpserver .
export type Application = express.Application | ||
|
||
export type Server = http.Server |
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.
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.
Co-authored-by: Mihovil Ilakovac <mihovil@ilakovac.com>
app
and server
to server setupFn
app
and server
to server setupFn
Description
This PR adds
app
andserver
to the serversetupFn
, mainly as an escape hatch. Users can then do arbitrary Express endpoints, or things like websockets.It is the start of #268, but the real finish there is adding some proper
api
DSL support.Select what type of change this PR introduces:
Update Waspc ChangeLog and version if needed
If you did a bug fix, new feature, or breaking change, that affects waspc, make sure you satisfy the following: