Skip to content
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

Feature request that makes anything runnable #2874

Closed
wants to merge 1 commit into from

Conversation

EloB
Copy link

@EloB EloB commented Jan 30, 2016

This is a draft for a new method that I call app.runnable(). It's almost works the same as app.listen() but it will only start the server if the current file is the require.main.

I always create my middlewares as express instances instead of just module.exports = function(req, res, next) {};. I also add this snippet in the bottom section of all my middlewares:

var app = require('express')();
// ...
if (require.main === module) {
  app.listen(3000);
}

I really like this pattern because it's easy to run any middleware as a service with just node middlewares/something.js. If you add some environment variables then it's really easy to scale a specific area of your application as well.

I haven't written any tests because I want to feedback from you guys what you think about this feature before I will write them.

Examples

Example 1

node index.js

Example 2

node middlewares/api.js

Example 3

EXPRESS_PORT=3001 EXPRESS_HOSTNAME=localhost node middlewares/api.js
EXPRESS_PATH=/var/tmp/http.sock node index.js

@wesleytodd
Copy link
Member

We use a similar pattern but for our apps in an SOA architecture, so not on a per middleware basis. It is a nice pattern, BUT, I think this would make a better third party module that wraps express, not necessarily a part of core. But that's just my 2c.

EDIT: And if you make it I would love to use it, because we have yet to get around to abstracting that out of our apps. :)

@EloB
Copy link
Author

EloB commented Jan 30, 2016

I think it's good if it's part of core because then it will be documented on http://expressjs.com/. That will add awareness to people how to make good use of express.

EDIT: Thanks for feedback @wesleytodd :)

@EloB
Copy link
Author

EloB commented Jan 30, 2016

I was thinking of another method name app.microservice(). What do you think about that?

@Twipped
Copy link

Twipped commented Jan 30, 2016

Express' entire direction is a reduction of API to increase simplicity and expandability. Express is also moving away from the idea of mounted applications, favoring routers instead. This idea directly conflicts with both of those goals.

I agree with @wesleytodd, this belongs in a third party lib.

@EloB
Copy link
Author

EloB commented Jan 30, 2016

@ChiperSoft Where can I read about moving away from mounting applications? I would say that is one of the best feature with express. I would probably move away from express if that gets deprecated. 👎

Anyway thanks for feedback! 😄

@EloB
Copy link
Author

EloB commented Jan 30, 2016

I think this method brings more to the table than app.listen() that is just a wrapper around http.createServer().listen(). If express goes against simplicity they should remove app.listen() as well.
Almost everything that you write is lightweight microservices with express and you need a easy way of distributing/scale them over time.
I think it will make your code cleaner if I don't have to require a extra plugin in your middleware/services. That also will bloat every service/middleware that you write and also extend installation time.

@Twipped
Copy link

Twipped commented Jan 30, 2016

@ChiperSoft https://github.com/ChiperSoft Where can I read about moving away from mounting applications? I would say that is one of the best feature with express.

I don't know of any specific places it's written about. It's the impression that I got from conversations with @dougwilson and from his comments in various issues and pull requests.

@wesleytodd
Copy link
Member

Hey @EloB, I was using this pattern today and ended up just publishing a module that does this: https://github.com/wesleytodd/runnable

Does that solve your problems?

@EloB
Copy link
Author

EloB commented Feb 9, 2016

@wesleytodd except that you can't have multiple runnable instances. If something requires runnable and it's resolves module.parent.parent as true then all other runnable will also be executed. That's why I use callsite.

@wesleytodd
Copy link
Member

@EloB Do you have an example? I would love to make sure that module works for it. I just used it in the case similar to what I have been doing, which is a bin script and an entry point which is runnable.

@Fishrock123
Copy link
Contributor

Seems to me that in the future this would mostly be possible with routers themselves, so I'm not sure I see the value, though I may have missed something.

@wesleytodd
Copy link
Member

Hey @Fishrock123, this specific feature makes the script directly runnable or "requireable". For example:

// index.js
module.exports = runnable(function () {
  var app = express();
  return app.listen();
});
// bin/start
#! /usr/local/env node

var app = require('../index');

// do some other configuration loading stuff, or like we use this 
// pattern for register with Consul our service discover layer

// Then start server

app();

With a setup like this you can run node index.js directly and it will start the server right away. Or you can run ./bin/start which will also start the server but after doing whatever other stuff you need to do.

I think @EloB's use case is something more like microservices where you can run one directly, or compose them together into a larger application. Correct me if I am wrong @EloB.

@EloB
Copy link
Author

EloB commented Feb 12, 2016

@wesleytodd @Fishrock123: You are right. Project tends to start small and then grow over time. If you structure your app to have everything as microservice. Then you could easily start a piece of your application in a separate process without any overhead. You don't need to refactor your application either and together with docker for instance this is awesome.

If I get some more spare time I could show how this could be used together with Docker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants