diff --git a/EXPRESSJS NODEJS FRAMEWORK b/EXPRESSJS NODEJS FRAMEWORK new file mode 100644 index 0000000..484f13b --- /dev/null +++ b/EXPRESSJS NODEJS FRAMEWORK @@ -0,0 +1,3091 @@ +# Hello GitHub Actions + +_Create and run a GitHub Actions workflow._ + +## Welcome + +Automation is key for repetitive tasks like testing, scanning, review, and deployment processes, and [GitHub Actions](https://docs.github.com/actions) is the best way to streamline that workflow. + +- **Who is this for**: Developers, DevOps engineers, Security engineers +- **What you'll learn**: How to create GitHub Actions workflows, how to run them, and how to use them to automate tasks. +- **What you'll build**: An Actions workflow that will comment on a pull request when it is created. +- **Prerequisites**: [Introduction to GitHub](https://github.com/skills/introduction-to-github) +- **How long**: This exercise can be finished in less than 30min. + +In this exercise, you will: + +1. Create a workflow file +1. Add a job +1. Add a run step +1. See the workflow run +1. Merge your pull request + +### How to start this exercise + +Simply copy the exercise to your account, then give your favorite Octocat (Mona) **about 20 seconds** to prepare the first lesson, then **refresh the page**. + +[![](https://img.shields.io/badge/Copy%20Exercise-%E2%86%92-1f883d?style=for-the-badge&logo=github&labelColor=197935)](https://github.com/new?template_owner=skills&template_name=hello-github-actions&owner=%40me&name=skills-hello-github-actions&description=Exercise:+Create+and+run+a+GitHub+Actions+Workflow&visibility=public) + +
+Having trouble? 🤷
+ +When copying the exercise, we recommend the following settings: + +- For owner, choose your personal account or an organization to host the repository. + +- We recommend creating a public repository, since private repositories will use Actions minutes. + +If the exercise isn't ready in 20 seconds, please check the [Actions](../../actions) tab. + +- Check to see if a job is running. Sometimes it simply takes a bit longer. + +- If the page shows a failed job, please submit an issue. Nice, you found a bug! 🐛 + +
+ +--- + +© 2025 GitHub • [Code of Conduct](https://www.contributor-covenant.org/version/2/1/code_of_conduct/code_of_conduct.md) • [MIT License](https://gh.io/mit) + +Expressjs NodeJS Framework. + + +Express Application Generator +npx command (available in Node.js 8.2.0). + +$ npx express-generator + +For earlier Node versions, install the application generator as a global npm package and then launch it: + +$ npm install -g express-generator +$ express + +Display the command options with the -h option: + +$ express -h + + Usage: express [options] [dir] + + Options: + + -h, --help output usage information + --version output the version number + -e, --ejs add ejs engine support + --hbs add handlebars engine support + --pug add pug engine support + -H, --hogan add hogan.js engine support + --no-view generate without view engine + -v, --view add view support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade) + -c, --css add stylesheet support (less|stylus|compass|sass) (defaults to plain css) + --git add .gitignore + -f, --force force on non-empty directory + +the following creates an Express app named myapp. The app will be created in a folder named myapp in the current working directory and the view engine will be set to Pug: + +$ express --view=pug myapp + + create : myapp + create : myapp/package.json + create : myapp/app.js + create : myapp/public + create : myapp/public/javascripts + create : myapp/public/images + create : myapp/routes + create : myapp/routes/index.js + create : myapp/routes/users.js + create : myapp/public/stylesheets + create : myapp/public/stylesheets/style.css + create : myapp/views + create : myapp/views/index.pug + create : myapp/views/layout.pug + create : myapp/views/error.pug + create : myapp/bin + create : myapp/bin/www + +Then install dependencies: + +$ cd myapp +$ npm install + +On MacOS or Linux, run the app with this command: + +$ DEBUG=myapp:* npm start + +On Windows Command Prompt, use this command: + +> set DEBUG=myapp:* & npm start + +On Windows PowerShell, use this command: + +PS> $env:DEBUG='myapp:*'; npm start + +Then load http://localhost:3000/ in your browser to access the app. + +The generated app has the following directory structure: + +. +├── app.js +├── bin +│ └── www +├── package.json +├── public +│ ├── images +│ ├── javascripts +│ └── stylesheets +│ └── style.css +├── routes +│ ├── index.js +│ └── users.js +└── views + ├── error.pug + ├── index.pug + └── layout.pug + +7 directories, 9 files. + +Installing. +$ mkdir myapp +$ cd myapp + + Specifics of npm’s package.json handling. + +$ npm init + + + +entry point: (index.js) + +Enter app.js, or whatever you want the name of the main file to be. If you want it to be index.js, hit RETURN to accept the suggested default file name. + +Now install Express in the myapp directory and save it in the dependencies list. For example: + +$ npm install express + +To install Express temporarily and not add it to the dependencies list: + +$ npm install express --no-save + +By default with version npm 5.0+ npm install adds the module to the dependencies list in the package.json file; with earlier versions of npm, you must specify the --save option explicitly. Then, afterwards, running npm install in the app directory will automatically install modules in the dependencies list. + + +Hello World + +const express = require('express') +const app = express() +const port = 3000 + +app.get('/', (req, res) => { + res.send('Hello World!') +}) + +app.listen(port, () => { + console.log(`Example app listening on port ${port}`) +}) + +This app starts a server and listens on port 3000 for connections. The app responds with “Hello World!” for requests to the root URL (/) or route. + +Running Locally +First create a directory named myapp, change to it and run npm init. Then install express as a dependency, as per the installation guide. + +In the myapp directory, create a file named app.js and copy in the code from the example above. + +The req (request) and res (response) are the exact same objects that Node provides, so you can invoke req.pipe(), req.on('data', callback), and anything else you would do without Express involved. + +Run the app with the following command: + +$ node app.js + +Then, load http://localhost:3000/ in a browser to see the output. + + +Basic routing +Routing refers to determining how an application responds to a client request to a particular endpoint, which is a URI (or path) and a specific HTTP request method (GET, POST, and so on). + +Each route can have one or more handler functions, which are executed when the route is matched. + +Route definition takes the following structure: + +app.METHOD(PATH, HANDLER) + +Where: + +app is an instance of express. +METHOD is an HTTP request method, in lowercase. +PATH is a path on the server. +HANDLER is the function executed when the route is matched. + + +Respond with Hello World! on the homepage: + +app.get('/', (req, res) => { + res.send('Hello World!') +}) + +Respond to POST request on the root route (/), the application’s home page: + +app.post('/', (req, res) => { + res.send('Got a POST request') +}) + +Respond to a PUT request to the /user route: + +app.put('/user', (req, res) => { + res.send('Got a PUT request at /user') +}) + +Respond to a DELETE request to the /user route: + +app.delete('/user', (req, res) => { + res.send('Got a DELETE request at /user') +}) + +Serving Static files in Express +express.static(root, [options]) + +The root argument specifies the root directory from which to serve static assets. For more information on the options argument, see express.static. + +For example, use the following code to serve images, CSS files, and JavaScript files in a directory named public: + +app.use(express.static('public')) + +Now, you can load the files that are in the public directory: + +http://localhost:3000/images/kitten.jpg +http://localhost:3000/css/style.css +http://localhost:3000/js/app.js +http://localhost:3000/images/bg.png +http://localhost:3000/hello.html + +Express looks up the files relative to the static directory, so the name of the static directory is not part of the URL. + +To use multiple static assets directories, call the express.static middleware function multiple times: + +app.use(express.static('public')) +app.use(express.static('files')) + +Express looks up the files in the order in which you set the static directories with the express.static middleware function. + +NOTE: For best results, use a reverse proxy cache to improve performance of serving static assets. + +To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the express.static function, specify a mount path for the static directory, as shown below: + +app.use('/static', express.static('public')) + +Now, you can load the files that are in the public directory from the /static path prefix. + +http://localhost:3000/static/images/kitten.jpg +http://localhost:3000/static/css/style.css +http://localhost:3000/static/js/app.js +http://localhost:3000/static/images/bg.png +http://localhost:3000/static/hello.html + +However, the path that you provide to the express.static function is relative to the directory from where you launch your node process. If you run the express app from another directory, it’s safer to use the absolute path of the directory that you want to serve: + +const path = require('path') +app.use('/static', express.static(path.join(__dirname, 'public'))) + +For more details about the serve-static function and its options, see serve-static. + + + +API Reference. +5.x API +Note: This is early beta documentation that may be incomplete and is still under development. + +express() +Creates an Express application. The express() function is a top-level function exported by the express module. + +const express = require('express') +const app = express() + +Methods +express.json([options]) +This is a built-in middleware function in Express. It parses incoming requests with JSON payloads and is based on body-parser. + +Returns middleware that only parses JSON and only looks at requests where the Content-Type header matches the type option. This parser accepts any Unicode encoding of the body and supports automatic inflation of gzip and deflate encodings. + +A new body object containing the parsed data is populated on the request object after the middleware (i.e. req.body), or an empty object ({}) if there was no body to parse, the Content-Type was not matched, or an error occurred. + +As req.body’s shape is based on user-controlled input, all properties and values in this object are untrusted and should be validated before trusting. For example, req.body.foo.toString() may fail in multiple ways, for example foo may not be there or may not be a string, and toString may not be a function and instead a string or other user-input. + +The following table describes the properties of the optional options object. + +Property Description Type Default +inflate Enables or disables handling deflated (compressed) bodies; when disabled, deflated bodies are rejected. Boolean true +limit Controls the maximum request body size. If this is a number, then the value specifies the number of bytes; if it is a string, the value is passed to the bytes library for parsing. Mixed "100kb" +reviver The reviver option is passed directly to JSON.parse as the second argument. You can find more information on this argument in the MDN documentation about JSON.parse. Function null +strict Enables or disables only accepting arrays and objects; when disabled will accept anything JSON.parse accepts. Boolean true +type This is used to determine what media type the middleware will parse. This option can be a string, array of strings, or a function. If not a function, type option is passed directly to the type-is library and this can be an extension name (like json), a mime type (like application/json), or a mime type with a wildcard (like */* or */json). If a function, the type option is called as fn(req) and the request is parsed if it returns a truthy value. Mixed "application/json" +verify This option, if supplied, is called as verify(req, res, buf, encoding), where buf is a Buffer of the raw request body and encoding is the encoding of the request. The parsing can be aborted by throwing an error. Function undefined +express.static(root, [options]) +This is a built-in middleware function in Express. It serves static files and is based on serve-static. + +NOTE: For best results, use a reverse proxy cache to improve performance of serving static assets. + +The root argument specifies the root directory from which to serve static assets. The function determines the file to serve by combining req.url with the provided root directory. When a file is not found, instead of sending a 404 response, it instead calls next() to move on to the next middleware, allowing for stacking and fall-backs. + +The following table describes the properties of the options object. See also the example below. + +Property Description Type Default +dotfiles Determines how dotfiles (files or directories that begin with a dot “.”) are treated. See dotfiles below. String “ignore” +etag Enable or disable etag generation NOTE: express.static always sends weak ETags. Boolean true +extensions Sets file extension fallbacks: If a file is not found, search for files with the specified extensions and serve the first one found. Example: ['html', 'htm']. Mixed false +fallthrough Let client errors fall-through as unhandled requests, otherwise forward a client error. See fallthrough below. Boolean true +immutable Enable or disable the immutable directive in the Cache-Control response header. If enabled, the maxAge option should also be specified to enable caching. The immutable directive will prevent supported clients from making conditional requests during the life of the maxAge option to check if the file has changed. Boolean false +index Sends the specified directory index file. Set to false to disable directory indexing. Mixed “index.html” +lastModified Set the Last-Modified header to the last modified date of the file on the OS. Boolean true +maxAge Set the max-age property of the Cache-Control header in milliseconds or a string in ms format. Number 0 +redirect Redirect to trailing “/” when the pathname is a directory. Boolean true +setHeaders Function for setting HTTP headers to serve with the file. See setHeaders below. Function +For more information, see Serving static files in Express. and Using middleware - Built-in middleware. + +dotfiles +Possible values for this option are: + +“allow” - No special treatment for dotfiles. +“deny” - Deny a request for a dotfile, respond with 403, then call next(). +“ignore” - Act as if the dotfile does not exist, respond with 404, then call next(). +fallthrough +When this option is true, client errors such as a bad request or a request to a non-existent file will cause this middleware to simply call next() to invoke the next middleware in the stack. When false, these errors (even 404s), will invoke next(err). + +Set this option to true so you can map multiple physical directories to the same web address or for routes to fill in non-existent files. + +Use false if you have mounted this middleware at a path designed to be strictly a single file system directory, which allows for short-circuiting 404s for less overhead. This middleware will also reply to all methods. + +For this option, specify a function to set custom response headers. Alterations to the headers must occur synchronously. + +The signature of the function is: + +fn(res, path, stat) + +Arguments: + +res, the response object. +path, the file path that is being sent. +stat, the stat object of the file that is being sent. +Example of express.static +Here is an example of using the express.static middleware function with an elaborate options object: + +const options = { + dotfiles: 'ignore', + etag: false, + extensions: ['htm', 'html'], + index: false, + maxAge: '1d', + redirect: false, + setHeaders (res, path, stat) { + res.set('x-timestamp', Date.now()) + } +} + +app.use(express.static('public', options)) + +express.Router([options]) +Creates a new router object. + +const router = express.Router([options]) + +The optional options parameter specifies the behavior of the router. + +You can add middleware and HTTP method routes (such as get, put, post, and so on) to router just like an application. + +For more information, see Router. + +express.urlencoded([options]) +This is a built-in middleware function in Express. It parses incoming requests with urlencoded payloads and is based on body-parser. + +Returns middleware that only parses urlencoded bodies and only looks at requests where the Content-Type header matches the type option. This parser accepts only UTF-8 encoding of the body and supports automatic inflation of gzip and deflate encodings. + +A new body object containing the parsed data is populated on the request object after the middleware (i.e. req.body), or an empty object ({}) if there was no body to parse, the Content-Type was not matched, or an error occurred. This object will contain key-value pairs, where the value can be a string or array (when extended is false), or any type (when extended is true). + +As req.body’s shape is based on user-controlled input, all properties and values in this object are untrusted and should be validated before trusting. For example, req.body.foo.toString() may fail in multiple ways, for example foo may not be there or may not be a string, and toString may not be a function and instead a string or other user-input. + +The following table describes the properties of the optional options object. + +Property Description Type Default +extended This option allows to choose between parsing the URL-encoded data with the querystring library (when false) or the qs library (when true). The “extended” syntax allows for rich objects and arrays to be encoded into the URL-encoded format, allowing for a JSON-like experience with URL-encoded. For more information, please see the qs library. Boolean false +inflate Enables or disables handling deflated (compressed) bodies; when disabled, deflated bodies are rejected. Boolean true +limit Controls the maximum request body size. If this is a number, then the value specifies the number of bytes; if it is a string, the value is passed to the bytes library for parsing. Mixed "100kb" +parameterLimit This option controls the maximum number of parameters that are allowed in the URL-encoded data. If a request contains more parameters than this value, an error will be raised. Number 1000 +type This is used to determine what media type the middleware will parse. This option can be a string, array of strings, or a function. If not a function, type option is passed directly to the type-is library and this can be an extension name (like urlencoded), a mime type (like application/x-www-form-urlencoded), or a mime type with a wildcard (like */x-www-form-urlencoded). If a function, the type option is called as fn(req) and the request is parsed if it returns a truthy value. Mixed "application/x-www-form-urlencoded" +verify This option, if supplied, is called as verify(req, res, buf, encoding), where buf is a Buffer of the raw request body and encoding is the encoding of the request. The parsing can be aborted by throwing an error. Function undefined +Application +The app object conventionally denotes the Express application. Create it by calling the top-level express() function exported by the Express module: + +const express = require('express') +const app = express() + +app.get('/', (req, res) => { + res.send('hello world') +}) + +app.listen(3000) + +The app object has methods for + +It also has settings (properties) that affect how the application behaves; for more information, see Application settings. + +Properties +app.locals +The app.locals object has properties that are local variables within the application, and will be available in templates rendered with res.render. + +console.dir(app.locals.title) +// => 'My App' + +console.dir(app.locals.email) +// => 'me@myapp.com' + +Once set, the value of app.locals properties persist throughout the life of the application, in contrast with res.locals properties that are valid only for the lifetime of the request. + +You can access local variables in templates rendered within the application. This is useful for providing helper functions to templates, as well as application-level data. Local variables are available in middleware via req.app.locals (see req.app) + +app.locals.title = 'My App' +app.locals.strftime = require('strftime') +app.locals.email = 'me@myapp.com' + +app.mountpath +The app.mountpath property contains one or more path patterns on which a sub-app was mounted. + +A sub-app is an instance of express that may be used for handling the request to a route. + +const express = require('express') + +const app = express() // the main app +const admin = express() // the sub app + +admin.get('/', (req, res) => { + console.log(admin.mountpath) // /admin + res.send('Admin Homepage') +}) + +app.use('/admin', admin) // mount the sub app + +It is similar to the baseUrl property of the req object, except req.baseUrl returns the matched URL path, instead of the matched patterns. + +If a sub-app is mounted on multiple path patterns, app.mountpath returns the list of patterns it is mounted on, as shown in the following example. + +const admin = express() + +admin.get('/', (req, res) => { + console.log(admin.mountpath) // [ '/adm*n', '/manager' ] + res.send('Admin Homepage') +}) + +const secret = express() +secret.get('/', (req, res) => { + console.log(secret.mountpath) // /secr*t + res.send('Admin Secret') +}) + +admin.use('/secr*t', secret) // load the 'secret' router on '/secr*t', on the 'admin' sub app +app.use(['/adm*n', '/manager'], admin) // load the 'admin' router on '/adm*n' and '/manager', on the parent app + +app.router +The application’s in-built instance of router. This is created lazily, on first access. + +const express = require('express') +const app = express() +const router = app.router + +router.get('/', (req, res) => { + res.send('hello world') +}) + +app.listen(3000) + +You can add middleware and HTTP method routes to the router just like an application. + +For more information, see Router. + +Events +app.on('mount', callback(parent)) +The mount event is fired on a sub-app, when it is mounted on a parent app. The parent app is passed to the callback function. + +NOTE + +Sub-apps will: + +Not inherit the value of settings that have a default value. You must set the value in the sub-app. +Inherit the value of settings with no default value. +For details, see Application settings. + +const admin = express() + +admin.on('mount', (parent) => { + console.log('Admin Mounted') + console.log(parent) // refers to the parent app +}) + +admin.get('/', (req, res) => { + res.send('Admin Homepage') +}) + +app.use('/admin', admin) + +Methods +app.all(path, callback [, callback ...]) +This method is like the standard app.METHOD() methods, except it matches all HTTP verbs. + +Arguments +Argument Description Default +path +The path for which the middleware function is invoked; can be any of: + +A string representing a path. +A path pattern. +A regular expression pattern to match paths. +An array of combinations of any of the above. +For examples, see Path examples. | '/' (root path) | | callback | Callback functions; can be: + +A middleware function. +A series of middleware functions (separated by commas). +An array of middleware functions. +A combination of all of the above. +You can provide multiple callback functions that behave just like middleware, except that these callbacks can invoke next('route') to bypass the remaining route callback(s). You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there is no reason to proceed with the current route. + +When a callback function throws an error or returns a rejected promise, next(err) will be invoked automatically. + +Since router and app implement the middleware interface, you can use them as you would any other middleware function. + +For examples, see Middleware callback function examples. | None | + +Examples +The following callback is executed for requests to /secret whether using GET, POST, PUT, DELETE, or any other HTTP request method: + +app.all('/secret', (req, res, next) => { + console.log('Accessing the secret section ...') + next() // pass control to the next handler +}) + +The app.all() method is useful for mapping “global” logic for specific path prefixes or arbitrary matches. For example, if you put the following at the top of all other route definitions, it requires that all routes from that point on require authentication, and automatically load a user. Keep in mind that these callbacks do not have to act as end-points: loadUser can perform a task, then call next() to continue matching subsequent routes. + +app.all('*', requireAuthentication, loadUser) + +Or the equivalent: + +app.all('*', requireAuthentication) +app.all('*', loadUser) + +Another example is white-listed “global” functionality. The example is similar to the ones above, but it only restricts paths that start with “/api”: + +app.all('/api/*', requireAuthentication) + +app.delete(path, callback [, callback ...]) +Routes HTTP DELETE requests to the specified path with the specified callback functions. For more information, see the routing guide. + +Arguments +Argument Description Default +path +The path for which the middleware function is invoked; can be any of: + +A string representing a path. +A path pattern. +A regular expression pattern to match paths. +An array of combinations of any of the above. +For examples, see Path examples. | '/' (root path) | | callback | Callback functions; can be: + +A middleware function. +A series of middleware functions (separated by commas). +An array of middleware functions. +A combination of all of the above. +You can provide multiple callback functions that behave just like middleware, except that these callbacks can invoke next('route') to bypass the remaining route callback(s). You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there is no reason to proceed with the current route. + +When a callback function throws an error or returns a rejected promise, next(err) will be invoked automatically. + +Since router and app implement the middleware interface, you can use them as you would any other middleware function. + +For examples, see Middleware callback function examples. | None | + +Example +app.delete('/', (req, res) => { + res.send('DELETE request to homepage') +}) + +app.disable(name) +Sets the Boolean setting name to false, where name is one of the properties from the app settings table. Calling app.set('foo', false) for a Boolean property is the same as calling app.disable('foo'). + +For example: + +app.disable('trust proxy') +app.get('trust proxy') +// => false + +app.disabled(name) +Returns true if the Boolean setting name is disabled (false), where name is one of the properties from the app settings table. + +app.disabled('trust proxy') +// => true + +app.enable('trust proxy') +app.disabled('trust proxy') +// => false + +app.enable(name) +Sets the Boolean setting name to true, where name is one of the properties from the app settings table. Calling app.set('foo', true) for a Boolean property is the same as calling app.enable('foo'). + +app.enable('trust proxy') +app.get('trust proxy') +// => true + +app.enabled(name) +Returns true if the setting name is enabled (true), where name is one of the properties from the app settings table. + +app.enabled('trust proxy') +// => false + +app.enable('trust proxy') +app.enabled('trust proxy') +// => true + +app.engine(ext, callback) +Registers the given template engine callback as ext. + +By default, Express will require() the engine based on the file extension. For example, if you try to render a “foo.pug” file, Express invokes the following internally, and caches the require() on subsequent calls to increase performance. + +app.engine('pug', require('pug').__express) + +Use this method for engines that do not provide .__express out of the box, or if you wish to “map” a different extension to the template engine. + +For example, to map the EJS template engine to “.html” files: + +app.engine('html', require('ejs').renderFile) + +In this case, EJS provides a .renderFile() method with the same signature that Express expects: (path, options, callback), though note that it aliases this method as ejs.__express internally so if you’re using “.ejs” extensions you don’t need to do anything. + +Some template engines do not follow this convention. The consolidate.js library maps Node template engines to follow this convention, so they work seamlessly with Express. + +const engines = require('consolidate') +app.engine('haml', engines.haml) +app.engine('html', engines.hogan) + +app.get(name) +Returns the value of name app setting, where name is one of the strings in the app settings table. For example: + +app.get('title') +// => undefined + +app.set('title', 'My Site') +app.get('title') +// => "My Site" + +app.get(path, callback [, callback ...]) +Routes HTTP GET requests to the specified path with the specified callback functions. + +Arguments +Argument Description Default +path +The path for which the middleware function is invoked; can be any of: + +A string representing a path. +A path pattern. +A regular expression pattern to match paths. +An array of combinations of any of the above. +For examples, see Path examples. | '/' (root path) | | callback | Callback functions; can be: + +A middleware function. +A series of middleware functions (separated by commas). +An array of middleware functions. +A combination of all of the above. +You can provide multiple callback functions that behave just like middleware, except that these callbacks can invoke next('route') to bypass the remaining route callback(s). You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there is no reason to proceed with the current route. + +When a callback function throws an error or returns a rejected promise, next(err) will be invoked automatically. + +Since router and app implement the middleware interface, you can use them as you would any other middleware function. + +For examples, see Middleware callback function examples. | None | + +For more information, see the routing guide. + +Example +app.get('/', (req, res) => { + res.send('GET request to homepage') +}) + +app.listen(path, [callback]) +Starts a UNIX socket and listens for connections on the given path. This method is identical to Node’s http.Server.listen(). + +const express = require('express') +const app = express() +app.listen('/tmp/sock') + +app.listen([port[, host[, backlog]]][, callback]) +Binds and listens for connections on the specified host and port. This method is identical to Node’s http.Server.listen(). + +If port is omitted or is 0, the operating system will assign an arbitrary unused port, which is useful for cases like automated tasks (tests, etc.). + +const express = require('express') +const app = express() +app.listen(3000) + +The app returned by express() is in fact a JavaScript Function, designed to be passed to Node’s HTTP servers as a callback to handle requests. This makes it easy to provide both HTTP and HTTPS versions of your app with the same code base, as the app does not inherit from these (it is simply a callback): + +const express = require('express') +const https = require('https') +const http = require('http') +const app = express() + +http.createServer(app).listen(80) +https.createServer(options, app).listen(443) + +The app.listen() method returns an http.Server object and (for HTTP) is a convenience method for the following: + +app.listen = function () { + const server = http.createServer(this) + return server.listen.apply(server, arguments) +} + +app.METHOD(path, callback [, callback ...]) +Routes an HTTP request, where METHOD is the HTTP method of the request, such as GET, PUT, POST, and so on, in lowercase. Thus, the actual methods are app.get(), app.post(), app.put(), and so on. See Routing methods below for the complete list. + +Arguments +Argument Description Default +path +The path for which the middleware function is invoked; can be any of: + +A string representing a path. +A path pattern. +A regular expression pattern to match paths. +An array of combinations of any of the above. +For examples, see Path examples. | '/' (root path) | | callback | Callback functions; can be: + +A middleware function. +A series of middleware functions (separated by commas). +An array of middleware functions. +A combination of all of the above. +You can provide multiple callback functions that behave just like middleware, except that these callbacks can invoke next('route') to bypass the remaining route callback(s). You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there is no reason to proceed with the current route. + +When a callback function throws an error or returns a rejected promise, next(err) will be invoked automatically. + +Since router and app implement the middleware interface, you can use them as you would any other middleware function. + +For examples, see Middleware callback function examples. | None | + +Routing methods +Express supports the following routing methods corresponding to the HTTP methods of the same names: + +* checkout +copy +delete +get +head +lock +merge +mkactivity | * mkcol +move +m-search +notify +options +patch +post | * purge +put +report +search +subscribe +trace +unlock +unsubscribe | +The API documentation has explicit entries only for the most popular HTTP methods app.get(), app.post(), app.put(), and app.delete(). However, the other methods listed above work in exactly the same way. + +To route methods that translate to invalid JavaScript variable names, use the bracket notation. For example, app['m-search'](https://github.com/https://apps.camposha.info/wp-content/uploads/md/node/expressjs/api/'/', function .... + +The app.get() function is automatically called for the HTTP HEAD method in addition to the GET method if app.head() was not called for the path before app.get(). + +The method, app.all(), is not derived from any HTTP method and loads middleware at the specified path for all HTTP request methods. For more information, see app.all. + +For more information on routing, see the routing guide. + +app.param(name, callback) +Add callback triggers to route parameters, where name is the name of the parameter or an array of them, and callback is the callback function. The parameters of the callback function are the request object, the response object, the next middleware, the value of the parameter and the name of the parameter, in that order. + +If name is an array, the callback trigger is registered for each parameter declared in it, in the order in which they are declared. Furthermore, for each declared parameter except the last one, a call to next inside the callback will call the callback for the next declared parameter. For the last parameter, a call to next will call the next middleware in place for the route currently being processed, just like it would if name were just a string. + +For example, when :user is present in a route path, you may map user loading logic to automatically provide req.user to the route, or perform validations on the parameter input. + +app.param('user', (req, res, next, id) => { + // try to get the user details from the User model and attach it to the request object + User.find(id, (err, user) => { + if (err) { + next(err) + } else if (user) { + req.user = user + next() + } else { + next(new Error('failed to load user')) + } + }) +}) + +Param callback functions are local to the router on which they are defined. They are not inherited by mounted apps or routers. Hence, param callbacks defined on app will be triggered only by route parameters defined on app routes. + +All param callbacks will be called before any handler of any route in which the param occurs, and they will each be called only once in a request-response cycle, even if the parameter is matched in multiple routes, as shown in the following examples. + +app.param('id', (req, res, next, id) => { + console.log('CALLED ONLY ONCE') + next() +}) + +app.get('/user/:id', (req, res, next) => { + console.log('although this matches') + next() +}) + +app.get('/user/:id', (req, res) => { + console.log('and this matches too') + res.end() +}) + +On GET /user/42, the following is printed: + +CALLED ONLY ONCE +although this matches +and this matches too + +app.param(['id', 'page'], (req, res, next, value) => { + console.log('CALLED ONLY ONCE with', value) + next() +}) + +app.get('/user/:id/:page', (req, res, next) => { + console.log('although this matches') + next() +}) + +app.get('/user/:id/:page', (req, res) => { + console.log('and this matches too') + res.end() +}) + +On GET /user/42/3, the following is printed: + +CALLED ONLY ONCE with 42 +CALLED ONLY ONCE with 3 +although this matches +and this matches too + +app.path() +Returns the canonical path of the app, a string. + +const app = express() +const blog = express() +const blogAdmin = express() + +app.use('/blog', blog) +blog.use('/admin', blogAdmin) + +console.log(app.path()) // '' +console.log(blog.path()) // '/blog' +console.log(blogAdmin.path()) // '/blog/admin' + +The behavior of this method can become very complicated in complex cases of mounted apps: it is usually better to use req.baseUrl to get the canonical path of the app. + +app.post(path, callback [, callback ...]) +Routes HTTP POST requests to the specified path with the specified callback functions. For more information, see the routing guide. + +Arguments +Argument Description Default +path +The path for which the middleware function is invoked; can be any of: + +A string representing a path. +A path pattern. +A regular expression pattern to match paths. +An array of combinations of any of the above. +For examples, see Path examples. | '/' (root path) | | callback | Callback functions; can be: + +A middleware function. +A series of middleware functions (separated by commas). +An array of middleware functions. +A combination of all of the above. +You can provide multiple callback functions that behave just like middleware, except that these callbacks can invoke next('route') to bypass the remaining route callback(s). You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there is no reason to proceed with the current route. + +When a callback function throws an error or returns a rejected promise, next(err) will be invoked automatically. + +Since router and app implement the middleware interface, you can use them as you would any other middleware function. + +For examples, see Middleware callback function examples. | None | + +Example +app.post('/', (req, res) => { + res.send('POST request to homepage') +}) + +app.put(path, callback [, callback ...]) +Routes HTTP PUT requests to the specified path with the specified callback functions. + +Arguments +Argument Description Default +path +The path for which the middleware function is invoked; can be any of: + +A string representing a path. +A path pattern. +A regular expression pattern to match paths. +An array of combinations of any of the above. +For examples, see Path examples. | '/' (root path) | | callback | Callback functions; can be: + +A middleware function. +A series of middleware functions (separated by commas). +An array of middleware functions. +A combination of all of the above. +You can provide multiple callback functions that behave just like middleware, except that these callbacks can invoke next('route') to bypass the remaining route callback(s). You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there is no reason to proceed with the current route. + +When a callback function throws an error or returns a rejected promise, next(err) will be invoked automatically. + +Since router and app implement the middleware interface, you can use them as you would any other middleware function. + +For examples, see Middleware callback function examples. | None | + +Example +app.put('/', (req, res) => { + res.send('PUT request to homepage') +}) + +app.render(view, [locals], callback) +Returns the rendered HTML of a view via the callback function. It accepts an optional parameter that is an object containing local variables for the view. It is like res.render(), except it cannot send the rendered view to the client on its own. + +Think of app.render() as a utility function for generating rendered view strings. Internally res.render() uses app.render() to render views. + +The local variable cache is reserved for enabling view cache. Set it to true, if you want to cache view during development; view caching is enabled in production by default. + +app.render('email', (err, html) => { + // ... +}) + +app.render('email', { name: 'Tobi' }, (err, html) => { + // ... +}) + +app.route(path) +Returns an instance of a single route, which you can then use to handle HTTP verbs with optional middleware. Use app.route() to avoid duplicate route names (and thus typo errors). + +const app = express() + +app.route('/events') + .all((req, res, next) => { + // runs for all HTTP verbs first + // think of it as route specific middleware! + }) + .get((req, res, next) => { + res.json({}) + }) + .post((req, res, next) => { + // maybe add a new event... + }) + +app.set(name, value) +Assigns setting name to value. You may store any value that you want, but certain names can be used to configure the behavior of the server. These special names are listed in the app settings table. + +Calling app.set('foo', true) for a Boolean property is the same as calling app.enable('foo'). Similarly, calling app.set('foo', false) for a Boolean property is the same as calling app.disable('foo'). + +Retrieve the value of a setting with app.get(). + +app.set('title', 'My Site') +app.get('title') // "My Site" + +Application Settings +The following table lists application settings. + +Note that sub-apps will: + +Not inherit the value of settings that have a default value. You must set the value in the sub-app. +Inherit the value of settings with no default value; these are explicitly noted in the table below. +Exceptions: Sub-apps will inherit the value of trust proxy even though it has a default value (for backward-compatibility); Sub-apps will not inherit the value of view cache in production (when NODE_ENV is “production”). + +app.use([path,] callback [, callback...]) +Mounts the specified middleware function or functions at the specified path: the middleware function is executed when the base of the requested path matches path. + +Arguments +Argument Description Default +path +The path for which the middleware function is invoked; can be any of: + +A string representing a path. +A path pattern. +A regular expression pattern to match paths. +An array of combinations of any of the above. +For examples, see Path examples. | '/' (root path) | | callback | Callback functions; can be: + +A middleware function. +A series of middleware functions (separated by commas). +An array of middleware functions. +A combination of all of the above. +You can provide multiple callback functions that behave just like middleware, except that these callbacks can invoke next('route') to bypass the remaining route callback(s). You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there is no reason to proceed with the current route. + +When a callback function throws an error or returns a rejected promise, next(err) will be invoked automatically. + +Since router and app implement the middleware interface, you can use them as you would any other middleware function. + +For examples, see Middleware callback function examples. | None | + +Description +A route will match any path that follows its path immediately with a “/”. For example: app.use('/apple', ...) will match “/apple”, “/apple/images”, “/apple/images/news”, and so on. + +Since path defaults to “/”, middleware mounted without a path will be executed for every request to the app. + +For example, this middleware function will be executed for every request to the app: + +app.use((req, res, next) => { + console.log('Time: %d', Date.now()) + next() +}) + +NOTE + +Sub-apps will: + +Not inherit the value of settings that have a default value. You must set the value in the sub-app. +Inherit the value of settings with no default value. +For details, see Application settings. + +Middleware functions are executed sequentially, therefore the order of middleware inclusion is important. + +// this middleware will not allow the request to go beyond it +app.use((req, res, next) => { + res.send('Hello World') +}) + +// requests will never reach this route +app.get('/', (req, res) => { + res.send('Welcome') +}) + +Error-handling middleware + +Error-handling middleware always takes four arguments. You must provide four arguments to identify it as an error-handling middleware function. Even if you don’t need to use the next object, you must specify it to maintain the signature. Otherwise, the next object will be interpreted as regular middleware and will fail to handle errors. For details about error-handling middleware, see: Error handling. + +Define error-handling middleware functions in the same way as other middleware functions, except with four arguments instead of three, specifically with the signature (err, req, res, next)): + +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) + +Path examples +The following table provides some simple examples of valid path values for mounting middleware. + +Middleware callback function examples +The following table provides some simple examples of middleware functions that can be used as the callback argument to app.use(), app.METHOD(), and app.all(). Even though the examples are for app.use(), they are also valid for app.use(), app.METHOD(), and app.all(). + +Usage Example +Single Middleware You can define and mount a middleware function locally. +app.use((req, res, next) => { + next() +}) + +A router is valid middleware. + +const router = express.Router() +router.get('/', (req, res, next) => { + next() +}) +app.use(router) + +An Express app is valid middleware. + +const subApp = express() +subApp.get('/', (req, res, next) => { + next() +}) +app.use(subApp) + +| | Series of Middleware | You can specify more than one middleware function at the same mount path. + +const r1 = express.Router() +r1.get('/', (req, res, next) => { + next() +}) + +const r2 = express.Router() +r2.get('/', (req, res, next) => { + next() +}) + +app.use(r1, r2) + +| | Array | Use an array to group middleware logically. + +const r1 = express.Router() +r1.get('/', (req, res, next) => { + next() +}) + +const r2 = express.Router() +r2.get('/', (req, res, next) => { + next() +}) + +app.use([r1, r2]) + +| | Combination | You can combine all the above ways of mounting middleware. + +function mw1 (req, res, next) { next() } +function mw2 (req, res, next) { next() } + +const r1 = express.Router() +r1.get('/', (req, res, next) => { next() }) + +const r2 = express.Router() +r2.get('/', (req, res, next) => { next() }) + +const subApp = express() +subApp.get('/', (req, res, next) => { next() }) + +app.use(mw1, [mw2, r1, r2], subApp) + +| + +Following are some examples of using the express.static middleware in an Express app. + +Serve static content for the app from the “public” directory in the application directory: + +// GET /style.css etc +app.use(express.static(path.join(__dirname, 'public'))) + +Mount the middleware at “/static” to serve static content only when their request path is prefixed with “/static”: + +// GET /static/style.css etc. +app.use('/static', express.static(path.join(__dirname, 'public'))) + +Disable logging for static content requests by loading the logger middleware after the static middleware: + +app.use(express.static(path.join(__dirname, 'public'))) +app.use(logger()) + +Serve static files from multiple directories, but give precedence to “./public” over the others: + +app.use(express.static(path.join(__dirname, 'public'))) +app.use(express.static(path.join(__dirname, 'files'))) +app.use(express.static(path.join(__dirname, 'uploads'))) + +Request +The req object represents the HTTP request and has properties for the request query string, parameters, body, HTTP headers, and so on. In this documentation and by convention, the object is always referred to as req (and the HTTP response is res) but its actual name is determined by the parameters to the callback function in which you’re working. + +For example: + +app.get('/user/:id', (req, res) => { + res.send(`user ${req.params.id}`) +}) + +But you could just as well have: + +app.get('/user/:id', (request, response) => { + response.send(`user ${request.params.id}`) +}) + +The req object is an enhanced version of Node’s own request object and supports all built-in fields and methods. + +Properties +req.app +This property holds a reference to the instance of the Express application that is using the middleware. + +If you follow the pattern in which you create a module that just exports a middleware function and require() it in your main file, then the middleware can access the Express instance via req.app + +For example: + +// index.js +app.get('/viewdirectory', require('./mymiddleware.js')) + +// mymiddleware.js +module.exports = (req, res) => { + res.send(`The views directory is ${req.app.get('views')}`) +} + +req.baseUrl +The URL path on which a router instance was mounted. + +The req.baseUrl property is similar to the mountpath property of the app object, except app.mountpath returns the matched path pattern(s). + +For example: + +const greet = express.Router() + +greet.get('/jp', (req, res) => { + console.log(req.baseUrl) // /greet + res.send('Konichiwa!') +}) + +app.use('/greet', greet) // load the router on '/greet' + +Even if you use a path pattern or a set of path patterns to load the router, the baseUrl property returns the matched string, not the pattern(s). In the following example, the greet router is loaded on two path patterns. + +app.use(['/gre+t', '/hel{2}o'], greet) // load the router on '/gre+t' and '/hel{2}o' + +When a request is made to /greet/jp, req.baseUrl is “/greet”. When a request is made to /hello/jp, req.baseUrl is “/hello”. + +req.body +Contains key-value pairs of data submitted in the request body. By default, it is undefined, and is populated when you use body-parsing middleware such as body-parser and multer. + +As req.body’s shape is based on user-controlled input, all properties and values in this object are untrusted and should be validated before trusting. For example, req.body.foo.toString() may fail in multiple ways, for example foo may not be there or may not be a string, and toString may not be a function and instead a string or other user-input. + +The following example shows how to use body-parsing middleware to populate req.body. + +const app = require('express')() +const bodyParser = require('body-parser') +const multer = require('multer') // v1.0.5 +const upload = multer() // for parsing multipart/form-data + +app.use(bodyParser.json()) // for parsing application/json +app.use(bodyParser.urlencoded({ extended: true })) // for parsing application/x-www-form-urlencoded + +app.post('/profile', upload.array(), (req, res, next) => { + console.log(req.body) + res.json(req.body) +}) + +req.cookies +When using cookie-parser middleware, this property is an object that contains cookies sent by the request. If the request contains no cookies, it defaults to {}. + +// Cookie: name=tj +console.dir(req.cookies.name) +// => "tj" + +If the cookie has been signed, you have to use req.signedCookies. + +For more information, issues, or concerns, see cookie-parser. + +req.fresh +When the response is still “fresh” in the client’s cache true is returned, otherwise false is returned to indicate that the client cache is now stale and the full response should be sent. + +When a client sends the Cache-Control: no-cache request header to indicate an end-to-end reload request, this module will return false to make handling these requests transparent. + +Further details for how cache validation works can be found in the HTTP/1.1 Caching Specification. + +console.dir(req.fresh) +// => true + +req.host +Contains the host derived from the Host HTTP header. + +When the trust proxy setting does not evaluate to false, this property will instead get the value from the X-Forwarded-Host header field. This header can be set by the client or by the proxy. + +If there is more than one X-Forwarded-Host header in the request, the value of the first header is used. This includes a single header with comma-separated values, in which the first value is used. + +// Host: "example.com:3000" +console.dir(req.host) +// => 'example.com:3000' + +// Host: "[::1]:3000" +console.dir(req.host) +// => '[::1]:3000' + +req.hostname +Contains the hostname derived from the Host HTTP header. + +When the trust proxy setting does not evaluate to false, this property will instead get the value from the X-Forwarded-Host header field. This header can be set by the client or by the proxy. + +If there is more than one X-Forwarded-Host header in the request, the value of the first header is used. This includes a single header with comma-separated values, in which the first value is used. + +Prior to Express v4.17.0, the X-Forwarded-Host could not contain multiple values or be present more than once. + +// Host: "example.com:3000" +console.dir(req.hostname) +// => 'example.com' + +req.ip +Contains the remote IP address of the request. + +When the trust proxy setting does not evaluate to false, the value of this property is derived from the left-most entry in the X-Forwarded-For header. This header can be set by the client or by the proxy. + +console.dir(req.ip) +// => "127.0.0.1" + +req.ips +When the trust proxy setting does not evaluate to false, this property contains an array of IP addresses specified in the X-Forwarded-For request header. Otherwise, it contains an empty array. This header can be set by the client or by the proxy. + +For example, if X-Forwarded-For is client, proxy1, proxy2, req.ips would be ["client", "proxy1", "proxy2"], where proxy2 is the furthest downstream. + +req.method +Contains a string corresponding to the HTTP method of the request: GET, POST, PUT, and so on. + +req.originalUrl +req.url is not a native Express property, it is inherited from Node’s http module. + +This property is much like req.url; however, it retains the original request URL, allowing you to rewrite req.url freely for internal routing purposes. For example, the “mounting” feature of app.use() will rewrite req.url to strip the mount point. + +// GET /search?q=something +console.dir(req.originalUrl) +// => "/search?q=something" + +req.originalUrl is available both in middleware and router objects, and is a combination of req.baseUrl and req.url. Consider following example: + +// GET 'http://www.example.com/admin/new?sort=desc' +app.use('/admin', (req, res, next) => { + console.dir(req.originalUrl) // '/admin/new?sort=desc' + console.dir(req.baseUrl) // '/admin' + console.dir(req.path) // '/new' + next() +}) + +req.params +This property is an object containing properties mapped to the named route “parameters”. For example, if you have the route /user/:name, then the “name” property is available as req.params.name. This object defaults to {}. + +// GET /user/tj +console.dir(req.params.name) +// => "tj" + +When you use a regular expression for the route definition, capture groups are provided in the array using req.params[n], where n is the nth capture group. This rule is applied to unnamed wild card matches with string routes such as /file/*: + +// GET /file/javascripts/jquery.js +console.dir(req.params[0]) +// => "javascripts/jquery.js" + +If you need to make changes to a key in req.params, use the app.param handler. Changes are applicable only to parameters already defined in the route path. + +Any changes made to the req.params object in a middleware or route handler will be reset. + +NOTE: Express automatically decodes the values in req.params (using decodeURIComponent). + +req.path +Contains the path part of the request URL. + +// example.com/users?sort=desc +console.dir(req.path) +// => "/users" + +When called from a middleware, the mount point is not included in req.path. See app.use() for more details. + +req.protocol +Contains the request protocol string: either http or (for TLS requests) https. + +When the trust proxy setting does not evaluate to false, this property will use the value of the X-Forwarded-Proto header field if present. This header can be set by the client or by the proxy. + +console.dir(req.protocol) +// => "http" + +req.query +This property is an object containing a property for each query string parameter in the route. When query parser is set to disabled, it is an empty object {}, otherwise it is the result of the configured query parser. + +As req.query’s shape is based on user-controlled input, all properties and values in this object are untrusted and should be validated before trusting. For example, req.query.foo.toString() may fail in multiple ways, for example foo may not be there or may not be a string, and toString may not be a function and instead a string or other user-input. + +The value of this property can be configured with the query parser application setting to work how your application needs it. A very popular query string parser is the qs module, and this is used by default. The qs module is very configurable with many settings, and it may be desirable to use different settings than the default to populate req.query: + +const qs = require('qs') +app.setting('query parser', + (str) => qs.parse(str, { /* custom options */ })) + +Check out the query parser application setting documentation for other customization options. + +req.res +This property holds a reference to the response object that relates to this request object. + +req.route +Contains the currently-matched route, a string. For example: + +app.get('/user/:id?', (req, res) => { + console.log(req.route) + res.send('GET') +}) + +Example output from the previous snippet: + +{ path: '/user/:id?', + stack: + [ { handle: [Function: userIdHandler], + name: 'userIdHandler', + params: undefined, + path: undefined, + keys: [], + regexp: /^/?$/i, + method: 'get' } ], + methods: { get: true } } + +req.secure +A Boolean property that is true if a TLS connection is established. Equivalent to the following: + +req.protocol === 'https' + +req.signedCookies +When using cookie-parser middleware, this property contains signed cookies sent by the request, unsigned and ready for use. Signed cookies reside in a different object to show developer intent; otherwise, a malicious attack could be placed on req.cookie values (which are easy to spoof). Note that signing a cookie does not make it “hidden” or encrypted; but simply prevents tampering (because the secret used to sign is private). + +If no signed cookies are sent, the property defaults to {}. + +// Cookie: user=tobi.CP7AWaXDfAKIRfH49dQzKJx7sKzzSoPq7/AcBBRVwlI3 +console.dir(req.signedCookies.user) +// => "tobi" + +For more information, issues, or concerns, see cookie-parser. + +req.stale +Indicates whether the request is “stale,” and is the opposite of req.fresh. For more information, see req.fresh. + +console.dir(req.stale) +// => true + +req.subdomains +An array of subdomains in the domain name of the request. + +// Host: "tobi.ferrets.example.com" +console.dir(req.subdomains) +// => ["ferrets", "tobi"] + +The application property subdomain offset, which defaults to 2, is used for determining the beginning of the subdomain segments. To change this behavior, change its value using app.set. + +req.xhr +A Boolean property that is true if the request’s X-Requested-With header field is “XMLHttpRequest”, indicating that the request was issued by a client library such as jQuery. + +console.dir(req.xhr) +// => true + +Methods +req.accepts(types) +Checks if the specified content types are acceptable, based on the request’s Accept HTTP header field. The method returns the best match, or if none of the specified content types is acceptable, returns false (in which case, the application should respond with 406 "Not Acceptable"). + +The type value may be a single MIME type string (such as “application/json”), an extension name such as “json”, a comma-delimited list, or an array. For a list or array, the method returns the best match (if any). + +// Accept: text/html +req.accepts('html') +// => "html" + +// Accept: text/*, application/json +req.accepts('html') +// => "html" +req.accepts('text/html') +// => "text/html" +req.accepts(['json', 'text']) +// => "json" +req.accepts('application/json') +// => "application/json" + +// Accept: text/*, application/json +req.accepts('image/png') +req.accepts('png') +// => false + +// Accept: text/*;q=.5, application/json +req.accepts(['html', 'json']) +// => "json" + +For more information, or if you have issues or concerns, see accepts. + +req.acceptsCharsets(charset [, ...]) +Returns the first accepted charset of the specified character sets, based on the request’s Accept-Charset HTTP header field. If none of the specified charsets is accepted, returns false. + +For more information, or if you have issues or concerns, see accepts. + +req.acceptsEncodings(encoding [, ...]) +Returns the first accepted encoding of the specified encodings, based on the request’s Accept-Encoding HTTP header field. If none of the specified encodings is accepted, returns false. + +For more information, or if you have issues or concerns, see accepts. + +req.acceptsLanguages(lang [, ...]) +Returns the first accepted language of the specified languages, based on the request’s Accept-Language HTTP header field. If none of the specified languages is accepted, returns false. + +For more information, or if you have issues or concerns, see accepts. + +req.get(field) +Returns the specified HTTP request header field (case-insensitive match). The Referrer and Referer fields are interchangeable. + +req.get('Content-Type') +// => "text/plain" + +req.get('content-type') +// => "text/plain" + +req.get('Something') +// => undefined + +Aliased as req.header(field). + +req.is(type) +Returns the matching content type if the incoming request’s “Content-Type” HTTP header field matches the MIME type specified by the type parameter. If the request has no body, returns null. Returns false otherwise. + +// With Content-Type: text/html; charset=utf-8 +req.is('html') // => 'html' +req.is('text/html') // => 'text/html' +req.is('text/*') // => 'text/*' + +// When Content-Type is application/json +req.is('json') // => 'json' +req.is('application/json') // => 'application/json' +req.is('application/*') // => 'application/*' + +req.is('html') +// => false + +For more information, or if you have issues or concerns, see type-is. + +req.range(size[, options]) +Range header parser. + +The size parameter is the maximum size of the resource. + +The options parameter is an object that can have the following properties. + +Property Type Description +combine Boolean Specify if overlapping & adjacent ranges should be combined, defaults to false. When true, ranges will be combined and returned as if they were specified that way in the header. +An array of ranges will be returned or negative numbers indicating an error parsing. + +-2 signals a malformed header string +-1 signals an unsatisfiable range +// parse header from request +const range = req.range(1000) + +// the type of the range +if (range.type === 'bytes') { + // the ranges + range.forEach((r) => { + // do something with r.start and r.end + }) +} + +Response +The res object represents the HTTP response that an Express app sends when it gets an HTTP request. + +In this documentation and by convention, the object is always referred to as res (and the HTTP request is req) but its actual name is determined by the parameters to the callback function in which you’re working. + +For example: + +app.get('/user/:id', (req, res) => { + res.send(`user ${req.params.id}`) +}) + +But you could just as well have: + +app.get('/user/:id', (request, response) => { + response.send(`user ${request.params.id}`) +}) + +The res object is an enhanced version of Node’s own response object and supports all built-in fields and methods. + +Properties +res.app +This property holds a reference to the instance of the Express application that is using the middleware. + +res.app is identical to the req.app property in the request object. + +Boolean property that indicates if the app sent HTTP headers for the response. + +app.get('/', (req, res) => { + console.log(res.headersSent) // false + res.send('OK') + console.log(res.headersSent) // true +}) + +res.locals +Use this property to set variables accessible in templates rendered with res.render. The variables set on res.locals are available within a single request-response cycle, and will not be shared between requests. + +In order to keep local variables for use in template rendering between requests, use app.locals instead. + +This property is useful for exposing request-level information such as the request path name, authenticated user, user settings, and so on to templates rendered within the application. + +app.use((req, res, next) => { + // Make `user` and `authenticated` available in templates + res.locals.user = req.user + res.locals.authenticated = !req.user.anonymous + next() +}) + +res.req +This property holds a reference to the request object that relates to this response object. + +Methods +res.append(field [, value]) +res.append() is supported by Express v4.11.0+ + +Appends the specified value to the HTTP response header field. If the header is not already set, it creates the header with the specified value. The value parameter can be a string or an array. + +Note: calling res.set() after res.append() will reset the previously-set header value. + +res.append('Link', ['', '']) +res.append('Set-Cookie', 'foo=bar; Path=/; HttpOnly') +res.append('Warning', '199 Miscellaneous warning') + +res.attachment([filename]) +Sets the HTTP response Content-Disposition header field to “attachment”. If a filename is given, then it sets the Content-Type based on the extension name via res.type(), and sets the Content-Disposition “filename=” parameter. + +res.attachment() +// Content-Disposition: attachment + +res.attachment('path/to/logo.png') +// Content-Disposition: attachment; filename="logo.png" +// Content-Type: image/png + +res.cookie(name, value [, options]) +Sets cookie name to value. The value parameter may be a string or object converted to JSON. + +The options parameter is an object that can have the following properties. + +Property Type Description +domain String Domain name for the cookie. Defaults to the domain name of the app. +encode Function A synchronous function used for cookie value encoding. Defaults to encodeURIComponent. +expires Date Expiry date of the cookie in GMT. If not specified or set to 0, creates a session cookie. +httpOnly Boolean Flags the cookie to be accessible only by the web server. +maxAge Number Convenient option for setting the expiry time relative to the current time in milliseconds. +path String Path for the cookie. Defaults to “/”. +secure Boolean Marks the cookie to be used with HTTPS only. +signed Boolean Indicates if the cookie should be signed. +sameSite Boolean or String Value of the “SameSite” Set-Cookie attribute. More information at https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00#section-4.1.1. +All res.cookie() does is set the HTTP Set-Cookie header with the options provided. Any option not specified defaults to the value stated in RFC 6265. + +For example: + +res.cookie('name', 'tobi', { domain: '.example.com', path: '/admin', secure: true }) +res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true }) + +The encode option allows you to choose the function used for cookie value encoding. Does not support asynchronous functions. + +Example use case: You need to set a domain-wide cookie for another site in your organization. This other site (not under your administrative control) does not use URI-encoded cookie values. + +// Default encoding +res.cookie('some_cross_domain_cookie', 'http://mysubdomain.example.com', { domain: 'example.com' }) +// Result: 'some_cross_domain_cookie=http%3A%2F%2Fmysubdomain.example.com; Domain=example.com; Path=/' + +// Custom encoding +res.cookie('some_cross_domain_cookie', 'http://mysubdomain.example.com', { domain: 'example.com', encode: String }) +// Result: 'some_cross_domain_cookie=http://mysubdomain.example.com; Domain=example.com; Path=/;' + +The maxAge option is a convenience option for setting “expires” relative to the current time in milliseconds. The following is equivalent to the second example above. + +res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true }) + +You can pass an object as the value parameter; it is then serialized as JSON and parsed by bodyParser() middleware. + +res.cookie('cart', { items: [1, 2, 3] }) +res.cookie('cart', { items: [1, 2, 3] }, { maxAge: 900000 }) + +When using cookie-parser middleware, this method also supports signed cookies. Simply include the signed option set to true. Then res.cookie() will use the secret passed to cookieParser(secret) to sign the value. + +res.cookie('name', 'tobi', { signed: true }) + +Later you may access this value through the req.signedCookies object. + +res.clearCookie(name [, options]) +Clears the cookie specified by name. For details about the options object, see res.cookie(). + +Web browsers and other compliant clients will only clear the cookie if the given options is identical to those given to res.cookie(), excluding expires and maxAge. + +res.cookie('name', 'tobi', { path: '/admin' }) +res.clearCookie('name', { path: '/admin' }) + +res.download(path [, filename] [, options] [, fn]) +The optional options argument is supported by Express v4.16.0 onwards. + +Transfers the file at path as an “attachment”. Typically, browsers will prompt the user for download. By default, the Content-Disposition header “filename=” parameter is derrived from the path argument, but can be overridden with the filename parameter. If path is relative, then it will be based on the current working directory of the process. + +The following table provides details on the options parameter. + +The optional options argument is supported by Express v4.16.0 onwards. + +The method invokes the callback function fn(err) when the transfer is complete or when an error occurs. If the callback function is specified and an error occurs, the callback function must explicitly handle the response process either by ending the request-response cycle, or by passing control to the next route. + +res.download('/report-12345.pdf') + +res.download('/report-12345.pdf', 'report.pdf') + +res.download('/report-12345.pdf', 'report.pdf', (err) => { + if (err) { + // Handle error, but keep in mind the response may be partially-sent + // so check res.headersSent + } else { + // decrement a download credit, etc. + } +}) + +res.end([data] [, encoding]) +Ends the response process. This method actually comes from Node core, specifically the response.end() method of http.ServerResponse. + +Use to quickly end the response without any data. If you need to respond with data, instead use methods such as res.send() and res.json(). + +res.end() +res.status(404).end() + +res.format(object) +Performs content-negotiation on the Accept HTTP header on the request object, when present. It uses req.accepts() to select a handler for the request, based on the acceptable types ordered by their quality values. If the header is not specified, the first callback is invoked. When no match is found, the server responds with 406 “Not Acceptable”, or invokes the default callback. + +The Content-Type response header is set when a callback is selected. However, you may alter this within the callback using methods such as res.set() or res.type(). + +The following example would respond with { "message": "hey" } when the Accept header field is set to “application/json” or “/json” (however if it is “/*”, then the response will be “hey”). + +res.format({ + 'text/plain' () { + res.send('hey') + }, + + 'text/html' () { + res.send('

hey

') + }, + + 'application/json' () { + res.send({ message: 'hey' }) + }, + + default () { + // log the request and respond with 406 + res.status(406).send('Not Acceptable') + } +}) + +In addition to canonicalized MIME types, you may also use extension names mapped to these types for a slightly less verbose implementation: + +res.format({ + text () { + res.send('hey') + }, + + html () { + res.send('

hey

') + }, + + json () { + res.send({ message: 'hey' }) + } +}) + +res.get(field) +Returns the HTTP response header specified by field. The match is case-insensitive. + +res.get('Content-Type') +// => "text/plain" + +res.json([body]) +Sends a JSON response. This method sends a response (with the correct content-type) that is the parameter converted to a JSON string using JSON.stringify(). + +The parameter can be any JSON type, including object, array, string, Boolean, number, or null, and you can also use it to convert other values to JSON. + +res.json(null) +res.json({ user: 'tobi' }) +res.status(500).json({ error: 'message' }) + +res.jsonp([body]) +Sends a JSON response with JSONP support. This method is identical to res.json(), except that it opts-in to JSONP callback support. + +res.jsonp(null) +// => callback(null) + +res.jsonp({ user: 'tobi' }) +// => callback({ "user": "tobi" }) + +res.status(500).jsonp({ error: 'message' }) +// => callback({ "error": "message" }) + +By default, the JSONP callback name is simply callback. Override this with the jsonp callback name setting. + +The following are some examples of JSONP responses using the same code: + +// ?callback=foo +res.jsonp({ user: 'tobi' }) +// => foo({ "user": "tobi" }) + +app.set('jsonp callback name', 'cb') + +// ?cb=foo +res.status(500).jsonp({ error: 'message' }) +// => foo({ "error": "message" }) + +res.links(links) +Joins the links provided as properties of the parameter to populate the response’s Link HTTP header field. + +For example, the following call: + +res.links({ + next: 'http://api.example.com/users?page=2', + last: 'http://api.example.com/users?page=5' +}) + +Yields the following results: + +Link: ; rel="next", + ; rel="last" + +res.location(path) +Sets the response Location HTTP header to the specified path parameter. + +res.location('/foo/bar') +res.location('http://example.com') +res.location('back') + +A path value of “back” has a special meaning, it refers to the URL specified in the Referer header of the request. If the Referer header was not specified, it refers to “/”. + +After encoding the URL, if not encoded already, Express passes the specified URL to the browser in the Location header, without any validation. + +Browsers take the responsibility of deriving the intended URL from the current URL or the referring URL, and the URL specified in the Location header; and redirect the user accordingly. + +res.redirect([status,] path) +Redirects to the URL derived from the specified path, with specified status, a positive integer that corresponds to an HTTP status code . If not specified, status defaults to “302 “Found”. + +res.redirect('/foo/bar') +res.redirect('http://example.com') +res.redirect(301, 'http://example.com') +res.redirect('../login') + +Redirects can be a fully-qualified URL for redirecting to a different site: + +res.redirect('http://google.com') + +Redirects can be relative to the root of the host name. For example, if the application is on http://example.com/admin/post/new, the following would redirect to the URL http://example.com/admin: + +res.redirect('/admin') + +Redirects can be relative to the current URL. For example, from http://example.com/blog/admin/ (notice the trailing slash), the following would redirect to the URL http://example.com/blog/admin/post/new. + +res.redirect('post/new') + +Redirecting to post/new from http://example.com/blog/admin (no trailing slash), will redirect to http://example.com/blog/post/new. + +If you found the above behavior confusing, think of path segments as directories (with trailing slashes) and files, it will start to make sense. + +Path-relative redirects are also possible. If you were on http://example.com/admin/post/new, the following would redirect to http://example.com/admin/post: + +res.redirect('..') + +A back redirection redirects the request back to the referer, defaulting to / when the referer is missing. + +res.redirect('back') + +res.render(view [, locals] [, callback]) +Renders a view and sends the rendered HTML string to the client. Optional parameters: + +locals, an object whose properties define local variables for the view. +callback, a callback function. If provided, the method returns both the possible error and rendered string, but does not perform an automated response. When an error occurs, the method invokes next(err) internally. +The view argument is a string that is the file path of the view file to render. This can be an absolute path, or a path relative to the views setting. If the path does not contain a file extension, then the view engine setting determines the file extension. If the path does contain a file extension, then Express will load the module for the specified template engine (via require()) and render it using the loaded module’s __express function. + +For more information, see Using template engines with Express. + +NOTE: The view argument performs file system operations like reading a file from disk and evaluating Node.js modules, and as so for security reasons should not contain input from the end-user. + +The local variable cache enables view caching. Set it to true, to cache the view during development; view caching is enabled in production by default. + +// send the rendered view to the client +res.render('index') + +// if a callback is specified, the rendered HTML string has to be sent explicitly +res.render('index', (err, html) => { + res.send(html) +}) + +// pass a local variable to the view +res.render('user', { name: 'Tobi' }, (err, html) => { + // ... +}) + +res.send([body]) +Sends the HTTP response. + +The body parameter can be a Buffer object, a String, an object, Boolean, or an Array. For example: + +res.send(Buffer.from('whoop')) +res.send({ some: 'json' }) +res.send('

some html

') +res.status(404).send('Sorry, we cannot find that!') +res.status(500).send({ error: 'something blew up' }) + +This method performs many useful tasks for simple non-streaming responses: For example, it automatically assigns the Content-Length HTTP response header field (unless previously defined) and provides automatic HEAD and HTTP cache freshness support. + +When the parameter is a Buffer object, the method sets the Content-Type response header field to “application/octet-stream”, unless previously defined as shown below: + +res.set('Content-Type', 'text/html') +res.send(Buffer.from('

some html

')) + +When the parameter is a String, the method sets the Content-Type to “text/html”: + +res.send('

some html

') + +When the parameter is an Array or Object, Express responds with the JSON representation: + +res.send({ user: 'tobi' }) +res.send([1, 2, 3]) + +res.sendFile(path [, options] [, fn]) +res.sendFile() is supported by Express v4.8.0 onwards. + +Transfers the file at the given path. Sets the Content-Type response HTTP header field based on the filename’s extension. Unless the root option is set in the options object, path must be an absolute path to the file. + +This API provides access to data on the running file system. Ensure that either (a) the way in which the path argument was constructed into an absolute path is secure if it contains user input or (b) set the root option to the absolute path of a directory to contain access within. + +When the root option is provided, the path argument is allowed to be a relative path, including containing ... Express will validate that the relative path provided as path will resolve within the given root option. + +The following table provides details on the options parameter. + +The method invokes the callback function fn(err) when the transfer is complete or when an error occurs. If the callback function is specified and an error occurs, the callback function must explicitly handle the response process either by ending the request-response cycle, or by passing control to the next route. + +Here is an example of using res.sendFile with all its arguments. + +app.get('/file/:name', (req, res, next) => { + const options = { + root: path.join(__dirname, 'public'), + dotfiles: 'deny', + headers: { + 'x-timestamp': Date.now(), + 'x-sent': true + } + } + + const fileName = req.params.name + res.sendFile(fileName, options, (err) => { + if (err) { + next(err) + } else { + console.log('Sent:', fileName) + } + }) +}) + +The following example illustrates using res.sendFile to provide fine-grained support for serving files: + +app.get('/user/:uid/photos/:file', (req, res) => { + const uid = req.params.uid + const file = req.params.file + + req.user.mayViewFilesFrom(uid, (yes) => { + if (yes) { + res.sendFile(`/uploads/${uid}/${file}`) + } else { + res.status(403).send("Sorry! You can't see that.") + } + }) +}) + +For more information, or if you have issues or concerns, see send. + +res.sendStatus(statusCode) +Sets the response HTTP status code to statusCode and sends the registered status message as the text response body. If an unknown status code is specified, the response body will just be the code number. + +res.sendStatus(404) + +Some versions of Node.js will throw when res.statusCode is set to an invalid HTTP status code (outside of the range 100 to 599). Consult the HTTP server documentation for the Node.js version being used. + +More about HTTP Status Codes + +res.set(field [, value]) +Sets the response’s HTTP header field to value. To set multiple fields at once, pass an object as the parameter. + +res.set('Content-Type', 'text/plain') + +res.set({ + 'Content-Type': 'text/plain', + 'Content-Length': '123', + ETag: '12345' +}) + +Aliased as res.header(field [, value]). + +res.status(code) +Sets the HTTP status for the response. It is a chainable alias of Node’s response.statusCode. + +res.status(403).end() +res.status(400).send('Bad Request') +res.status(404).sendFile('/absolute/path/to/404.png') + +res.type(type) +Sets the Content-Type HTTP header to the MIME type as determined by the specified type. If type contains the “/” character, then it sets the Content-Type to the exact value of type, otherwise it is assumed to be a file extension and the MIME type is looked up in a mapping using the express.static.mime.lookup() method. + +res.type('.html') // => 'text/html' +res.type('html') // => 'text/html' +res.type('json') // => 'application/json' +res.type('application/json') // => 'application/json' +res.type('png') // => image/png: + +res.vary(field) +Adds the field to the Vary response header, if it is not there already. + +res.vary('User-Agent').render('docs') + +Router +A router object is an isolated instance of middleware and routes. You can think of it as a “mini-application,” capable only of performing middleware and routing functions. Every Express application has a built-in app router. + +A router behaves like middleware itself, so you can use it as an argument to app.use() or as the argument to another router’s use() method. + +The top-level express object has a Router() method that creates a new router object. + +Once you’ve created a router object, you can add middleware and HTTP method routes (such as get, put, post, and so on) to it just like an application. For example: + +// invoked for any requests passed to this router +router.use((req, res, next) => { + // .. some logic here .. like any other middleware + next() +}) + +// will handle any request that ends in /events +// depends on where the router is "use()'d" +router.get('/events', (req, res, next) => { + // .. +}) + +You can then use a router for a particular root URL in this way separating your routes into files or even mini-apps. + +// only requests to /calendar/* will be sent to our "router" +app.use('/calendar', router) + +Methods +router.all(path, [callback, ...] callback) +This method is just like the router.METHOD() methods, except that it matches all HTTP methods (verbs). + +This method is extremely useful for mapping “global” logic for specific path prefixes or arbitrary matches. For example, if you placed the following route at the top of all other route definitions, it would require that all routes from that point on would require authentication, and automatically load a user. Keep in mind that these callbacks do not have to act as end points; loadUser can perform a task, then call next() to continue matching subsequent routes. + +router.all('*', requireAuthentication, loadUser) + +Or the equivalent: + +router.all('*', requireAuthentication) +router.all('*', loadUser) + +Another example of this is white-listed “global” functionality. Here the example is much like before, but it only restricts paths prefixed with “/api”: + +router.all('/api/*', requireAuthentication) + +router.METHOD(path, [callback, ...] callback) +The router.METHOD() methods provide the routing functionality in Express, where METHOD is one of the HTTP methods, such as GET, PUT, POST, and so on, in lowercase. Thus, the actual methods are router.get(), router.post(), router.put(), and so on. + +The router.get() function is automatically called for the HTTP HEAD method in addition to the GET method if router.head() was not called for the path before router.get(). + +You can provide multiple callbacks, and all are treated equally, and behave just like middleware, except that these callbacks may invoke next('route') to bypass the remaining route callback(s). You can use this mechanism to perform pre-conditions on a route then pass control to subsequent routes when there is no reason to proceed with the route matched. + +The following snippet illustrates the most simple route definition possible. Express translates the path strings to regular expressions, used internally to match incoming requests. Query strings are not considered when performing these matches, for example “GET /” would match the following route, as would “GET /?name=tobi”. + +router.get('/', (req, res) => { + res.send('hello world') +}) + +You can also use regular expressions—useful if you have very specific constraints, for example the following would match “GET /commits/71dbb9c” as well as “GET /commits/71dbb9c..4c084f9”. + +router.get(/^/commits/(w+)(?:..(w+))?$/, (req, res) => { + const from = req.params[0] + const to = req.params[1] || 'HEAD' + res.send(`commit range ${from}..${to}`) +}) + +You can use next primitive to implement a flow control between different middleware functions, based on a specific program state. Invoking next with the string 'router' will cause all the remaining route callbacks on that router to be bypassed. + +The following example illustrates next('router') usage. + +function fn (req, res, next) { + console.log('I come here') + next('router') +} +router.get('/foo', fn, (req, res, next) => { + console.log('I dont come here') +}) +router.get('/foo', (req, res, next) => { + console.log('I dont come here') +}) +app.get('/foo', (req, res) => { + console.log(' I come here too') + res.end('good') +}) + +router.param(name, callback) +Adds callback triggers to route parameters, where name is the name of the parameter and callback is the callback function. Although name is technically optional, using this method without it is deprecated starting with Express v4.11.0 (see below). + +The parameters of the callback function are: + +req, the request object. +res, the response object. +next, indicating the next middleware function. +The value of the name parameter. +The name of the parameter. +Unlike app.param(), router.param() does not accept an array of route parameters. + +For example, when :user is present in a route path, you may map user loading logic to automatically provide req.user to the route, or perform validations on the parameter input. + +router.param('user', (req, res, next, id) => { + // try to get the user details from the User model and attach it to the request object + User.find(id, (err, user) => { + if (err) { + next(err) + } else if (user) { + req.user = user + next() + } else { + next(new Error('failed to load user')) + } + }) +}) + +Param callback functions are local to the router on which they are defined. They are not inherited by mounted apps or routers. Hence, param callbacks defined on router will be triggered only by route parameters defined on router routes. + +A param callback will be called only once in a request-response cycle, even if the parameter is matched in multiple routes, as shown in the following examples. + +router.param('id', (req, res, next, id) => { + console.log('CALLED ONLY ONCE') + next() +}) + +router.get('/user/:id', (req, res, next) => { + console.log('although this matches') + next() +}) + +router.get('/user/:id', (req, res) => { + console.log('and this matches too') + res.end() +}) + +On GET /user/42, the following is printed: + +CALLED ONLY ONCE +although this matches +and this matches too + +The following section describes router.param(callback), which is deprecated as of v4.11.0. + +The behavior of the router.param(name, callback) method can be altered entirely by passing only a function to router.param(). This function is a custom implementation of how router.param(name, callback) should behave - it accepts two parameters and must return a middleware. + +The first parameter of this function is the name of the URL parameter that should be captured, the second parameter can be any JavaScript object which might be used for returning the middleware implementation. + +The middleware returned by the function decides the behavior of what happens when a URL parameter is captured. + +In this example, the router.param(name, callback) signature is modified to router.param(name, accessId). Instead of accepting a name and a callback, router.param() will now accept a name and a number. + +const express = require('express') +const app = express() +const router = express.Router() + +// customizing the behavior of router.param() +router.param((param, option) => { + return (req, res, next, val) => { + if (val === option) { + next() + } else { + res.sendStatus(403) + } + } +}) + +// using the customized router.param() +router.param('id', 1337) + +// route to trigger the capture +router.get('/user/:id', (req, res) => { + res.send('OK') +}) + +app.use(router) + +app.listen(3000, () => { + console.log('Ready') +}) + +In this example, the router.param(name, callback) signature remains the same, but instead of a middleware callback, a custom data type checking function has been defined to validate the data type of the user id. + +router.param((param, validator) => { + return (req, res, next, val) => { + if (validator(val)) { + next() + } else { + res.sendStatus(403) + } + } +}) + +router.param('id', (candidate) => { + return !isNaN(parseFloat(candidate)) && isFinite(candidate) +}) + +router.route(path) +Returns an instance of a single route which you can then use to handle HTTP verbs with optional middleware. Use router.route() to avoid duplicate route naming and thus typing errors. + +Building on the router.param() example above, the following code shows how to use router.route() to specify various HTTP method handlers. + +const router = express.Router() + +router.param('user_id', (req, res, next, id) => { + // sample user, would actually fetch from DB, etc... + req.user = { + id, + name: 'TJ' + } + next() +}) + +router.route('/users/:user_id') + .all((req, res, next) => { + // runs for all HTTP verbs first + // think of it as route specific middleware! + next() + }) + .get((req, res, next) => { + res.json(req.user) + }) + .put((req, res, next) => { + // just an example of maybe updating the user + req.user.name = req.params.name + // save user ... etc + res.json(req.user) + }) + .post((req, res, next) => { + next(new Error('not implemented')) + }) + .delete((req, res, next) => { + next(new Error('not implemented')) + }) + +This approach re-uses the single /users/:user_id path and adds handlers for various HTTP methods. + +NOTE: When you use router.route(), middleware ordering is based on when the route is created, not when method handlers are added to the route. For this purpose, you can consider method handlers to belong to the route to which they were added. + +router.use([path], [function, ...] function) +Uses the specified middleware function or functions, with optional mount path path, that defaults to “/”. + +This method is similar to app.use(). A simple example and use case is described below. See app.use() for more information. + +Middleware is like a plumbing pipe: requests start at the first middleware function defined and work their way “down” the middleware stack processing for each path they match. + +const express = require('express') +const app = express() +const router = express.Router() + +// simple logger for this router's requests +// all requests to this router will first hit this middleware +router.use((req, res, next) => { + console.log('%s %s %s', req.method, req.url, req.path) + next() +}) + +// this will only be invoked if the path starts with /bar from the mount point +router.use('/bar', (req, res, next) => { + // ... maybe some additional /bar logging ... + next() +}) + +// always invoked +router.use((req, res, next) => { + res.send('Hello World') +}) + +app.use('/foo', router) + +app.listen(3000) + +The “mount” path is stripped and is not visible to the middleware function. The main effect of this feature is that a mounted middleware function may operate without code changes regardless of its “prefix” pathname. + +The order in which you define middleware with router.use() is very important. They are invoked sequentially, thus the order defines middleware precedence. For example, usually a logger is the very first middleware you would use, so that every request gets logged. + +const logger = require('morgan') + +router.use(logger()) +router.use(express.static(path.join(__dirname, 'public'))) +router.use((req, res) => { + res.send('Hello') +}) + +Now suppose you wanted to ignore logging requests for static files, but to continue logging routes and middleware defined after logger(). You would simply move the call to express.static() to the top, before adding the logger middleware: + +router.use(express.static(path.join(__dirname, 'public'))) +router.use(logger()) +router.use((req, res) => { + res.send('Hello') +}) + +Another example is serving files from multiple directories, giving precedence to “./public” over the others: + +app.use(express.static(path.join(__dirname, 'public'))) +app.use(express.static(path.join(__dirname, 'files'))) +app.use(express.static(path.join(__dirname, 'uploads'))) + +The router.use() method also supports named parameters so that your mount points for other routers can benefit from preloading using named parameters. + +NOTE: Although these middleware functions are added via a particular router, when they run is defined by the path they are attached to (not the router). Therefore, middleware added via one router may run for other routers if its routes match. For example, this code shows two different routers mounted on the same path: + +const authRouter = express.Router() +const openRouter = express.Router() + +authRouter.use(require('./authenticate').basic(usersdb)) + +authRouter.get('/:user_id/edit', (req, res, next) => { + // ... Edit user UI ... +}) +openRouter.get('/', (req, res, next) => { + // ... List users ... +}) +openRouter.get('/:user_id', (req, res, next) => { + // ... View user ... +}) + +app.use('/users', authRouter) +app.use('/users', openRouter) + +Even though the authentication middleware was added via the authRouter it will run on the routes defined by the openRouter as well since both routers were mounted on /users. To avoid this behavior, use different paths for each router. + + +Developing Template Engines for Express +Use the app.engine(ext, callback) method to create your own template engine. ext refers to the file extension, and callback is the template engine function, which accepts the following items as parameters: the location of the file, the options object, and the callback function. + +The following code is an example of implementing a very simple template engine for rendering .ntl files. + +const fs = require('fs') // this engine requires the fs module +app.engine('ntl', (filePath, options, callback) => { // define the template engine + fs.readFile(filePath, (err, content) => { + if (err) return callback(err) + // this is an extremely simple template engine + const rendered = content.toString() + .replace('#title#', `${options.title}`) + .replace('#message#', `

${options.message}

`) + return callback(null, rendered) + }) +}) +app.set('views', './views') // specify the views directory +app.set('view engine', 'ntl') // register the template engine + +Your app will now be able to render .ntl files. Create a file named index.ntl in the views directory with the following content. + +#title# +#message# + +Then, create the following route in your app. + +app.get('/', (req, res) => { + res.render('index', { title: 'Hey', message: 'Hello there!' }) +}) + +When you make a request to the home page, index.ntl will be rendered as HTML. + + + +Security Best Practice +Use Helmet +Helmet can help protect your app from some well-known web vulnerabilities by setting HTTP headers appropriately. + +Helmet is a collection of several smaller middleware functions that set security-related HTTP response headers. Some examples include: + +helmet.contentSecurityPolicy which sets the Content-Security-Policy header. This helps prevent cross-site scripting attacks among many other things. +helmet.hsts which sets the Strict-Transport-Security header. This helps enforce secure (HTTPS) connections to the server. +helmet.frameguard which sets the X-Frame-Options header. This provides clickjacking protection. +Helmet includes several other middleware functions which you can read about at its documentation website. + +Install Helmet like any other module: + +$ npm install --save helmet + +Then to use it in your code: + +// ... + +const helmet = require('helmet') +app.use(helmet()) + +// ... + +Reduce Fingerprinting +It can help to provide an extra layer of obsecurity to reduce server fingerprinting. Though not a security issue itself, a method to improve the overall posture of a web server is to take measures to reduce the ability to fingerprint the software being used on the server. Server software can be fingerprinted by kwirks in how they respond to specific requests. + +By default, Express.js sends the X-Powered-By response header banner. This can be disabled using the app.disable() method: + +app.disable('x-powered-by') + +Note: Disabling the X-Powered-By header does not prevent a sophisticated attacker from determining that an app is running Express. It may discourage a casual exploit, but there are other ways to determine an app is running Express. + +Express.js also sends it’s own formatted 404 Not Found messages and own formatter error response messages. These can be changed by adding your own not found handler and writing your own error handler: + +// last app.use calls right before app.listen(): + +// custom 404 +app.use((req, res, next) => { + res.status(404).send("Sorry can't find that!") +}) + +// custom error handler +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) + +Use cookies securely +To ensure cookies don’t open your app to exploits, don’t use the default session cookie name and set cookie security options appropriately. + +There are two main middleware cookie session modules: + +express-session that replaces express.session middleware built-in to Express 3.x. +cookie-session that replaces express.cookieSession middleware built-in to Express 3.x. +The main difference between these two modules is how they save cookie session data. The express-session middleware stores session data on the server; it only saves the session ID in the cookie itself, not session data. By default, it uses in-memory storage and is not designed for a production environment. In production, you’ll need to set up a scalable session-store; see the list of compatible session stores. + +In contrast, cookie-session middleware implements cookie-backed storage: it serializes the entire session to the cookie, rather than just a session key. Only use it when session data is relatively small and easily encoded as primitive values (rather than objects). Although browsers are supposed to support at least 4096 bytes per cookie, to ensure you don’t exceed the limit, don’t exceed a size of 4093 bytes per domain. Also, be aware that the cookie data will be visible to the client, so if there is any reason to keep it secure or obscure, then express-session may be a better choice. + +Don’t use the default session cookie name +Using the default session cookie name can open your app to attacks. The security issue posed is similar to X-Powered-By: a potential attacker can use it to fingerprint the server and target attacks accordingly. + +To avoid this problem, use generic cookie names; for example using express-session middleware: + +const session = require('express-session') +app.set('trust proxy', 1) // trust first proxy +app.use(session({ + secret: 's3Cur3', + name: 'sessionId' +})) + +Set cookie security options +Set the following cookie options to enhance security: + +secure - Ensures the browser only sends the cookie over HTTPS. +httpOnly - Ensures the cookie is sent only over HTTP(S), not client JavaScript, helping to protect against cross-site scripting attacks. +domain - indicates the domain of the cookie; use it to compare against the domain of the server in which the URL is being requested. If they match, then check the path attribute next. +path - indicates the path of the cookie; use it to compare against the request path. If this and domain match, then send the cookie in the request. +expires - use to set expiration date for persistent cookies. +Here is an example using cookie-session middleware: + +const session = require('cookie-session') +const express = require('express') +const app = express() + +const expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour +app.use(session({ + name: 'session', + keys: ['key1', 'key2'], + cookie: { + secure: true, + httpOnly: true, + domain: 'example.com', + path: 'foo/bar', + expires: expiryDate + } +})) + +Prevent brute-force attacks against authorization +Make sure login endpoints are protected to make private data more secure. + +A simple and powerful technique is to block authorization attempts using two metrics: + +The first is number of consecutive failed attempts by the same user name and IP address. +The second is number of failed attempts from an IP address over some long period of time. For example, block an IP address if it makes 100 failed attempts in one day. +rate-limiter-flexible package provides tools to make this technique easy and fast. You can find an example of brute-force protection in the documentation + +Ensure your dependencies are secure +Using npm to manage your application’s dependencies is powerful and convenient. But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the “weakest link” in your dependencies. + +Since npm@6, npm automatically reviews every install request. Also you can use ‘npm audit’ to analyze your dependency tree. + +$ npm audit + +If you want to stay more secure, consider Snyk. + +Snyk offers both a command-line tool and a Github integration that checks your application against Snyk’s open source vulnerability database for any known vulnerabilities in your dependencies. Install the CLI as follows: + +$ npm install -g snyk +$ cd your-app + +Use this command to test your application for vulnerabilities: + +$ snyk test + +Use this command to open a wizard that walks you through the process of applying updates or patches to fix the vulnerabilities that were found: + +$ snyk wizard + + +Performance Best Practices. + +Production best practices: performance and reliability +Overview +This article discusses performance and reliability best practices for Express applications deployed to production. + +This topic clearly falls into the “devops” world, spanning both traditional development and operations. Accordingly, the information is divided into two parts: + +Things to do in your code (the dev part): +Things to do in your environment / setup (the ops part): +Things to do in your code +Here are some things you can do in your code to improve your application’s performance: + +Use gzip compression +Gzip compressing can greatly decrease the size of the response body and hence increase the speed of a web app. Use the compression middleware for gzip compression in your Express app. For example: + +const compression = require('compression') +const express = require('express') +const app = express() +app.use(compression()) + +For a high-traffic website in production, the best way to put compression in place is to implement it at a reverse proxy level (see Use a reverse proxy). In that case, you do not need to use compression middleware. For details on enabling gzip compression in Nginx, see Module ngx_http_gzip_module in the Nginx documentation. + +Don’t use synchronous functions +Synchronous functions and methods tie up the executing process until they return. A single call to a synchronous function might return in a few microseconds or milliseconds, however in high-traffic websites, these calls add up and reduce the performance of the app. Avoid their use in production. + +Although Node and many modules provide synchronous and asynchronous versions of their functions, always use the asynchronous version in production. The only time when a synchronous function can be justified is upon initial startup. + +If you are using Node.js 4.0+ or io.js 2.1.0+, you can use the --trace-sync-io command-line flag to print a warning and a stack trace whenever your application uses a synchronous API. Of course, you wouldn’t want to use this in production, but rather to ensure that your code is ready for production. See the node command-line options documentation for more information. + +Do logging correctly +In general, there are two reasons for logging from your app: For debugging and for logging app activity (essentially, everything else). Using console.log() or console.error() to print log messages to the terminal is common practice in development. But these functions are synchronous when the destination is a terminal or a file, so they are not suitable for production, unless you pipe the output to another program. + +For debugging +If you’re logging for purposes of debugging, then instead of using console.log(), use a special debugging module like debug. This module enables you to use the DEBUG environment variable to control what debug messages are sent to console.error(), if any. To keep your app purely asynchronous, you’d still want to pipe console.error() to another program. But then, you’re not really going to debug in production, are you? + +For app activity +If you’re logging app activity (for example, tracking traffic or API calls), instead of using console.log(), use a logging library like Winston or Bunyan. For a detailed comparison of these two libraries, see the StrongLoop blog post Comparing Winston and Bunyan Node.js Logging. + +Handle exceptions properly +Node apps crash when they encounter an uncaught exception. Not handling exceptions and taking appropriate actions will make your Express app crash and go offline. If you follow the advice in Ensure your app automatically restarts below, then your app will recover from a crash. Fortunately, Express apps typically have a short startup time. Nevertheless, you want to avoid crashing in the first place, and to do that, you need to handle exceptions properly. + +To ensure you handle all exceptions, use the following techniques: + +Before diving into these topics, you should have a basic understanding of Node/Express error handling: using error-first callbacks, and propagating errors in middleware. Node uses an “error-first callback” convention for returning errors from asynchronous functions, where the first parameter to the callback function is the error object, followed by result data in succeeding parameters. To indicate no error, pass null as the first parameter. The callback function must correspondingly follow the error-first callback convention to meaningfully handle the error. And in Express, the best practice is to use the next() function to propagate errors through the middleware chain. + +For more on the fundamentals of error handling, see: + +What not to do +One thing you should not do is to listen for the uncaughtException event, emitted when an exception bubbles all the way back to the event loop. Adding an event listener for uncaughtException will change the default behavior of the process that is encountering an exception; the process will continue to run despite the exception. This might sound like a good way of preventing your app from crashing, but continuing to run the app after an uncaught exception is a dangerous practice and is not recommended, because the state of the process becomes unreliable and unpredictable. + +Additionally, using uncaughtException is officially recognized as crude. So listening for uncaughtException is just a bad idea. This is why we recommend things like multiple processes and supervisors: crashing and restarting is often the most reliable way to recover from an error. + +We also don’t recommend using domains. It generally doesn’t solve the problem and is a deprecated module. + +Use try-catch +Try-catch is a JavaScript language construct that you can use to catch exceptions in synchronous code. Use try-catch, for example, to handle JSON parsing errors as shown below. + +Use a tool such as JSHint or JSLint to help you find implicit exceptions like reference errors on undefined variables. + +Here is an example of using try-catch to handle a potential process-crashing exception. This middleware function accepts a query field parameter named “params” that is a JSON object. + +app.get('/search', (req, res) => { + // Simulating async operation + setImmediate(() => { + const jsonStr = req.query.params + try { + const jsonObj = JSON.parse(jsonStr) + res.send('Success') + } catch (e) { + res.status(400).send('Invalid JSON string') + } + }) +}) + +However, try-catch works only for synchronous code. Because the Node platform is primarily asynchronous (particularly in a production environment), try-catch won’t catch a lot of exceptions. + +Use promises +Promises will handle any exceptions (both explicit and implicit) in asynchronous code blocks that use then(). Just add .catch(next) to the end of promise chains. For example: + +app.get('/', (req, res, next) => { + // do some sync stuff + queryDb() + .then((data) => makeCsv(data)) // handle data + .then((csv) => { /* handle csv */ }) + .catch(next) +}) + +app.use((err, req, res, next) => { + // handle error +}) + +Now all errors asynchronous and synchronous get propagated to the error middleware. + +However, there are two caveats: + +All your asynchronous code must return promises (except emitters). If a particular library does not return promises, convert the base object by using a helper function like Bluebird.promisifyAll(). +Event emitters (like streams) can still cause uncaught exceptions. So make sure you are handling the error event properly; for example: +const wrap = fn => (...args) => fn(...args).catch(args[2]) + +app.get('/', wrap(async (req, res, next) => { + const company = await getCompanyById(req.query.id) + const stream = getLogoStreamById(company.id) + stream.on('error', next).pipe(res) +})) + +The wrap() function is a wrapper that catches rejected promises and calls next() with the error as the first argument. For details, see Asynchronous Error Handling in Express with Promises, Generators and ES7. + +For more information about error-handling by using promises, see Promises in Node.js with Q – An Alternative to Callbacks. + +Things to do in your environment / setup +Here are some things you can do in your system environment to improve your app’s performance: + +Set NODE_ENV to “production” +The NODE_ENV environment variable specifies the environment in which an application is running (usually, development or production). One of the simplest things you can do to improve performance is to set NODE_ENV to “production.” + +Setting NODE_ENV to “production” makes Express: + +Cache view templates. +Cache CSS files generated from CSS extensions. +Generate less verbose error messages. +Tests indicate that just doing this can improve app performance by a factor of three! + +If you need to write environment-specific code, you can check the value of NODE_ENV with process.env.NODE_ENV. Be aware that checking the value of any environment variable incurs a performance penalty, and so should be done sparingly. + +In development, you typically set environment variables in your interactive shell, for example by using export or your .bash_profile file. But in general you shouldn’t do that on a production server; instead, use your OS’s init system (systemd or Upstart). The next section provides more details about using your init system in general, but setting NODE_ENV is so important for performance (and easy to do), that it’s highlighted here. + +With Upstart, use the env keyword in your job file. For example: + +# /etc/init/env.conf + env NODE_ENV=production + +For more information, see the Upstart Intro, Cookbook and Best Practices. + +With systemd, use the Environment directive in your unit file. For example: + +# /etc/systemd/system/myservice.service +Environment=NODE_ENV=production + +For more information, see Using Environment Variables In systemd Units. + +Ensure your app automatically restarts +In production, you don’t want your application to be offline, ever. This means you need to make sure it restarts both if the app crashes and if the server itself crashes. Although you hope that neither of those events occurs, realistically you must account for both eventualities by: + +Using a process manager to restart the app (and Node) when it crashes. +Using the init system provided by your OS to restart the process manager when the OS crashes. It’s also possible to use the init system without a process manager. +Node applications crash if they encounter an uncaught exception. The foremost thing you need to do is to ensure your app is well-tested and handles all exceptions (see handle exceptions properly for details). But as a fail-safe, put a mechanism in place to ensure that if and when your app crashes, it will automatically restart. + +Use a process manager +In development, you started your app simply from the command line with node server.js or something similar. But doing this in production is a recipe for disaster. If the app crashes, it will be offline until you restart it. To ensure your app restarts if it crashes, use a process manager. A process manager is a “container” for applications that facilitates deployment, provides high availability, and enables you to manage the application at runtime. + +In addition to restarting your app when it crashes, a process manager can enable you to: + +Gain insights into runtime performance and resource consumption. +Modify settings dynamically to improve performance. +Control clustering (StrongLoop PM and pm2). +The most popular process managers for Node are as follows: + +For a feature-by-feature comparison of the three process managers, see http://strong-pm.io/compare/. For a more detailed introduction to all three, see Process managers for Express apps. + +Using any of these process managers will suffice to keep your application up, even if it does crash from time to time. + +However, StrongLoop PM has lots of features that specifically target production deployment. You can use it and the related StrongLoop tools to: + +Build and package your app locally, then deploy it securely to your production system. +Automatically restart your app if it crashes for any reason. +Manage your clusters remotely. +View CPU profiles and heap snapshots to optimize performance and diagnose memory leaks. +View performance metrics for your application. +Easily scale to multiple hosts with integrated control for Nginx load balancer. +As explained below, when you install StrongLoop PM as an operating system service using your init system, it will automatically restart when the system restarts. Thus, it will keep your application processes and clusters alive forever. + +Use an init system +The next layer of reliability is to ensure that your app restarts when the server restarts. Systems can still go down for a variety of reasons. To ensure that your app restarts if the server crashes, use the init system built into your OS. The two main init systems in use today are systemd and Upstart. + +There are two ways to use init systems with your Express app: + +Run your app in a process manager, and install the process manager as a service with the init system. The process manager will restart your app when the app crashes, and the init system will restart the process manager when the OS restarts. This is the recommended approach. +Run your app (and Node) directly with the init system. This is somewhat simpler, but you don’t get the additional advantages of using a process manager. +Systemd +Systemd is a Linux system and service manager. Most major Linux distributions have adopted systemd as their default init system. + +A systemd service configuration file is called a unit file, with a filename ending in .service. Here’s an example unit file to manage a Node app directly. Replace the values enclosed in for your system and app: + +[Unit] +Description= + +[Service] +Type=simple +ExecStart=/usr/local/bin/node +WorkingDirectory= + +User=nobody +Group=nogroup + +# Environment variables: +Environment=NODE_ENV=production + +# Allow many incoming connections +LimitNOFILE=infinity + +# Allow core dumps for debugging +LimitCORE=infinity + +StandardInput=null +StandardOutput=syslog +StandardError=syslog +Restart=always + +[Install] +WantedBy=multi-user.target + +For more information on systemd, see the systemd reference (man page). + +StrongLoop PM as a systemd service +You can easily install StrongLoop Process Manager as a systemd service. After you do, when the server restarts, it will automatically restart StrongLoop PM, which will then restart all the apps it is managing. + +To install StrongLoop PM as a systemd service: + +$ sudo sl-pm-install --systemd + +Then start the service with: + +$ sudo /usr/bin/systemctl start strong-pm + +For more information, see Setting up a production host (StrongLoop documentation). + +Upstart +Upstart is a system tool available on many Linux distributions for starting tasks and services during system startup, stopping them during shutdown, and supervising them. You can configure your Express app or process manager as a service and then Upstart will automatically restart it when it crashes. + +An Upstart service is defined in a job configuration file (also called a “job”) with filename ending in .conf. The following example shows how to create a job called “myapp” for an app named “myapp” with the main file located at /projects/myapp/index.js. + +Create a file named myapp.conf at /etc/init/ with the following content (replace the bold text with values for your system and app): + +# When to start the process +start on runlevel [2345] + +# When to stop the process +stop on runlevel [016] + +# Increase file descriptor limit to be able to handle more requests +limit nofile 50000 50000 + +# Use production mode +env NODE_ENV=production + +# Run as www-data +setuid www-data +setgid www-data + +# Run from inside the app dir +chdir /projects/myapp + +# The process to start +exec /usr/local/bin/node /projects/myapp/index.js + +# Restart the process if it is down +respawn + +# Limit restart attempt to 10 times within 10 seconds +respawn limit 10 10 + +NOTE: This script requires Upstart 1.4 or newer, supported on Ubuntu 12.04-14.10. + +Since the job is configured to run when the system starts, your app will be started along with the operating system, and automatically restarted if the app crashes or the system goes down. + +Apart from automatically restarting the app, Upstart enables you to use these commands: + +start myapp – Start the app +restart myapp – Restart the app +stop myapp – Stop the app. +For more information on Upstart, see Upstart Intro, Cookbook and Best Practises. + +StrongLoop PM as an Upstart service +You can easily install StrongLoop Process Manager as an Upstart service. After you do, when the server restarts, it will automatically restart StrongLoop PM, which will then restart all the apps it is managing. + +To install StrongLoop PM as an Upstart 1.4 service: + +$ sudo sl-pm-install + +Then run the service with: + +$ sudo /sbin/initctl start strong-pm + +NOTE: On systems that don’t support Upstart 1.4, the commands are slightly different. See Setting up a production host (StrongLoop documentation) for more information. + +Run your app in a cluster +In a multi-core system, you can increase the performance of a Node app by many times by launching a cluster of processes. A cluster runs multiple instances of the app, ideally one instance on each CPU core, thereby distributing the load and tasks among the instances. + +Balancing between application instances using the cluster API + +IMPORTANT: Since the app instances run as separate processes, they do not share the same memory space. That is, objects are local to each instance of the app. Therefore, you cannot maintain state in the application code. However, you can use an in-memory datastore like Redis to store session-related data and state. This caveat applies to essentially all forms of horizontal scaling, whether clustering with multiple processes or multiple physical servers. + +In clustered apps, worker processes can crash individually without affecting the rest of the processes. Apart from performance advantages, failure isolation is another reason to run a cluster of app processes. Whenever a worker process crashes, always make sure to log the event and spawn a new process using cluster.fork(). + +Using Node’s cluster module +Clustering is made possible with Node’s cluster module. This enables a master process to spawn worker processes and distribute incoming connections among the workers. However, rather than using this module directly, it’s far better to use one of the many tools out there that does it for you automatically; for example node-pm or cluster-service. + +Using StrongLoop PM +If you deploy your application to StrongLoop Process Manager (PM), then you can take advantage of clustering without modifying your application code. + +When StrongLoop Process Manager (PM) runs an application, it automatically runs it in a cluster with a number of workers equal to the number of CPU cores on the system. You can manually change the number of worker processes in the cluster using the slc command line tool without stopping the app. + +For example, assuming you’ve deployed your app to prod.foo.com and StrongLoop PM is listening on port 8701 (the default), then to set the cluster size to eight using slc: + +$ slc ctl -C http://prod.foo.com:8701 set-size my-app 8 + +For more information on clustering with StrongLoop PM, see Clustering in StrongLoop documentation. + +Using PM2 +If you deploy your application with PM2, then you can take advantage of clustering without modifying your application code. You should ensure your application is stateless first, meaning no local data is stored in the process (such as sessions, websocket connections and the like). + +When running an application with PM2, you can enable cluster mode to run it in a cluster with a number of instances of your choosing, such as the matching the number of available CPUs on the machine. You can manually change the number of processes in the cluster using the pm2 command line tool without stopping the app. + +To enable cluster mode, start your application like so: + +# Start 4 worker processes +$ pm2 start npm --name my-app -i 4 -- start +# Auto-detect number of available CPUs and start that many worker processes +$ pm2 start npm --name my-app -i max -- start + +This can also be configured within a PM2 process file (ecosystem.config.js or similar) by setting exec_mode to cluster and instances to the number of workers to start. + +Once running, the application can be scaled like so: + +# Add 3 more workers +$ pm2 scale my-app +3 +# Scale to a specific number of workers +$ pm2 scale my-app 2 + +For more information on clustering with PM2, see Cluster Mode in the PM2 documentation. + +Cache request results +Another strategy to improve the performance in production is to cache the result of requests, so that your app does not repeat the operation to serve the same request repeatedly. + +Use a caching server like Varnish or Nginx (see also Nginx Caching) to greatly improve the speed and performance of your app. + +Use a load balancer +No matter how optimized an app is, a single instance can handle only a limited amount of load and traffic. One way to scale an app is to run multiple instances of it and distribute the traffic via a load balancer. Setting up a load balancer can improve your app’s performance and speed, and enable it to scale more than is possible with a single instance. + +A load balancer is usually a reverse proxy that orchestrates traffic to and from multiple application instances and servers. You can easily set up a load balancer for your app by using Nginx or HAProxy. + +With load balancing, you might have to ensure that requests that are associated with a particular session ID connect to the process that originated them. This is known as session affinity, or sticky sessions, and may be addressed by the suggestion above to use a data store such as Redis for session data (depending on your application). For a discussion, see Using multiple nodes. + +Use a reverse proxy +A reverse proxy sits in front of a web app and performs supporting operations on the requests, apart from directing requests to the app. It can handle error pages, compression, caching, serving files, and load balancing among other things. + +Handing over tasks that do not require knowledge of application state to a reverse proxy frees up Express to perform specialized application tasks. For this reason, it is recommended to run Express behind a reverse proxy like Nginx or HAProxy in production. + + + +Health Checks and Graceful Shutdown +Graceful shutdown +When you deploy a new version of your application, you must replace the previous version. The process manager you’re using will first send a SIGTERM signal to the application to notify it that it will be killed. Once the application gets this signal, it should stop accepting new requests, finish all the ongoing requests, clean up the resources it used, including database connections and file locks then exit. + +Example Graceful Shutdown +const server = app.listen(port) + +process.on('SIGTERM', () => { + debug('SIGTERM signal received: closing HTTP server') + server.close(() => { + debug('HTTP server closed') + }) +}) + +Health checks +A load balancer uses health checks to determine if an application instance is healthy and can accept requests. For example, Kubernetes has two health checks: + +liveness, that determines when to restart a container. +readiness, that determines when a container is ready to start accepting traffic. When a pod is not ready, it is removed from the service load balancers. +Third-party solutions +Warning: This information refers to third-party sites, products, or modules that are not maintained by the Expressjs team. Listing here does not constitute an endorsement or recommendation from the Expressjs project team. + +Terminus +Terminus is an open-source project that adds health checks and graceful shutdown to your application to eliminate the need to write boilerplate code. You just provide the cleanup logic for graceful shutdowns and the health check logic for health checks, and terminus handles the rest. + +Install terminus as follows: + +$ npm i @godaddy/terminus --save + +Here’s a basic template that illustrates using terminus. For more information, see https://github.com/godaddy/terminus. + +const http = require('http') +const express = require('express') +const { createTerminus } = require('@godaddy/terminus') + +const app = express() + +app.get('/', (req, res) => { + res.send('ok') +}) + +const server = http.createServer(app) + +function onSignal () { + console.log('server is starting cleanup') + // start cleanup of resource, like databases or file descriptors +} + +async function onHealthCheck () { + // checks if the system is healthy, like the db connection is live + // resolves, if health, rejects if not +} + +createTerminus(server, { + signal: 'SIGINT', + healthChecks: { '/healthcheck': onHealthCheck }, + onSignal +}) + +server.listen(3000) + +Lightship +Lightship is an open-source project that adds health, readiness and liveness checks to your application. Lightship is a standalone HTTP-service that runs as a separate HTTP service; this allows having health-readiness-liveness HTTP endpoints without exposing them on the public interface. + +Install Lightship as follows: + +$ npm install lightship + +Basic template that illustrates using Lightship: + +const http = require('http') +const express = require('express') +const { + createLightship +} = require('lightship') + +// Lightship will start a HTTP service on port 9000. +const lightship = createLightship() + +const app = express() + +app.get('/', (req, res) => { + res.send('ok') +}) + +app.listen(3000, () => { + lightship.signalReady() +}) + +// You can signal that the service is not ready using `lightship.signalNotReady()`. + +Lightship documentation provides examples of the corresponding Kubernetes configuration and a complete example of integration with Express.js. + +http-terminator +http-terminator implements logic for gracefully terminating an express.js server. + +Terminating a HTTP server in Node.js requires keeping track of all open connections and signaling them that the server is shutting down. http-terminator implements the logic for tracking all connections and their termination upon a timeout. http-terminator also ensures graceful communication of the server intention to shutdown to any clients that are currently receiving response from this server. + +Install http-terminator as follows: + +$ npm install http-terminator + +Basic template that illustrates using http-terminator: + +const express = require('express') +const { createHttpTerminator } = require('http-terminator') + +const app = express() + +const server = app.listen(3000) + +const httpTerminator = createHttpTerminator({ server }) + +app.get('/', (req, res) => { + res.send('ok') +}) + +// A server will terminate after invoking `httpTerminator.terminate()`. +// Note: Timeout is used for illustration of delayed termination purposes only. +setTimeout(() => { + httpTerminator.terminate() +}, 1000) + +http-terminator documentation provides API documentation and comparison to other existing third-party solutions. + +express-actuator +express-actuator is a middleware to add endpoints to help you monitor and manage applications. + +Install express-actuator as follows: + +$ npm install --save express-actuator + +Basic template that illustrates using express-actuator: + +const express = require('express') +const actuator = require('express-actuator') + +const app = express() + +app.use(actuator()) + +app.listen(3000) + +The express-actuator documentation provides different options for customization. + + +Resources. +# Template engines + +**Warning**: +The packages listed below may be outdated, no longer maintained or even broken. Listing here does not constitute an endorsement or recommendation from the Expressjs project team. Use at your own risk. + + + +These template engines work “out-of-the-box” with Express: + + +* **[Pug](https://github.com/pugjs/pug)**: Haml-inspired template engine (formerly Jade). +* **[Haml.js](https://github.com/tj/haml.js)**: Haml implementation. +* **[EJS](https://github.com/mde/ejs)**: Embedded JavaScript template engine. +* **[hbs](https://github.com/pillarjs/hbs)**: Adapter for Handlebars.js, an extension of Mustache.js template engine. +* **[Squirrelly](https://github.com/squirrellyjs/squirrelly)**: Blazing-fast template engine that supports partials, helpers, custom tags, filters, and caching. Not white-space sensitive, works with any language. +* **[Eta](https://github.com/eta-dev/eta)**: Super-fast lightweight embedded JS template engine. Supports custom delimiters, async, whitespace control, partials, caching, plugins. +* **[combyne.js](https://github.com/tbranyen/combyne)**: A template engine that hopefully works the way you’d expect. +* **[Nunjucks](https://github.com/mozilla/nunjucks)**: Inspired by jinja/twig. +* **[marko](https://github.com/marko-js/marko)**: A fast and lightweight HTML-based templating engine that compiles templates to CommonJS modules and supports streaming, async rendering and custom tags. (Renders directly to the HTTP response stream). +* **[whiskers](https://github.com/gsf/whiskers.js)**: Small, fast, mustachioed. +* **[Blade](https://github.com/bminer/node-blade)**: HTML Template Compiler, inspired by Jade & Haml. +* **[Haml-Coffee](https://github.com/netzpirat/haml-coffee)**: Haml templates where you can write inline CoffeeScript. +* **[express-hbs](https://github.com/barc/express-hbs)**: Handlebars with layouts, partials and blocks for express 3 from Barc. +* **[express-handlebars](https://github.com/express-handlebars/express-handlebars)**: A Handlebars view engine for Express which doesn’t suck. +* **[express-views-dom](https://github.com/AndersDJohnson/express-views-dom)**: A DOM view engine for Express. +* **[rivets-server](https://github.com/AndersDJohnson/rivets-server)**: Render Rivets.js templates on the server. +* **[LiquidJS](https://github.com/harttle/liquidjs)**: A simple, expressive and safe template engine. +* **[express-tl](https://github.com/Drulac/express-tl)**: A template-literal engine implementation for Express. +* **[Twing](https://www.npmjs.com/package/twing)**: First-class Twig engine for Node.js. +* **[Sprightly](https://www.npmjs.com/package/sprightly)**: A very light-weight JS template engine (45 lines of code), that consists of all the bare-bones features that you want to see in a template engine. +* **[html-express-js](https://www.npmjs.com/package/html-express-js)**: A small template engine for those that want to just serve static or dynamic HTML pages using native JavaScript. + + +The [Consolidate.js](https://github.com/tj/consolidate.js) library unifies the APIs of these template engines to a single Express-compatible API. + + +### Add your template engine here! + + +[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/en/resources/template-engines.md) and add a link to your project, then submit a pull request (GitHub login required). Follow the format of the above listings. + +UTILITY MODULES. +## Express utility functions + +The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules +for utility functions that may be generally useful. + + +| Utility modules | Description | +| --- | --- | +| [cookies](https://www.npmjs.com/package/cookies) | Get and set HTTP(S) cookies that can be signed to prevent tampering, using Keygrip. Can be used with the Node.js HTTP library or as Express middleware. | +| [csrf](https://www.npmjs.com/package/csrf) | Contains the logic behind CSRF token creation and verification. Use this module to create custom CSRF middleware. | +| [finalhandler](https://www.npmjs.com/package/finalhandler) | Function to invoke as the final step to respond to HTTP request. | +| [parseurl](https://www.npmjs.com/package/parseurl) | Parse a URL with caching. | +| [path-match](https://www.npmjs.com/package/path-match) | Thin wrapper around [path-to-regexp](https://github.com/component/path-to-regexp) to make extracting parameter names easier. | +| [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | Turn an Express-style path string such as ``/user/:name` into a regular expression. | +| [resolve-path](https://www.npmjs.com/package/resolve-path) | Resolves a relative path against a root path with validation. | +| [router](https://www.npmjs.com/package/router) | Simple middleware-style router. | +| [routington](https://www.npmjs.com/package/routington) | Trie-based URL router for defining and matching URLs. | +| [send](https://www.npmjs.com/package/send) | Library for streaming files as a HTTP response, with support for partial responses (ranges), conditional-GET negotiation, and granular events. | +| [templation](https://www.npmjs.com/package/templation) | View system similar to `res.render()` inspired by [co-views](https://github.com/visionmedia/co-views) and [consolidate.js](https://github.com/visionmedia/consolidate.js/). | + + +For additional low-level HTTP-related modules, see [jshttp](http://jshttp.github.io/) . + + +Frameworks. +# Frameworks built on Express. + +**Warning**: +This information refers to third-party sites, +products, or modules that are not maintained by the Expressjs team. Listing here does not constitute +an endorsement or recommendation from the Expressjs project team. + +Several popular Node.js frameworks are built on Express: + + +* **[Feathers](http://feathersjs.com)**: Build prototypes in minutes and production ready real-time apps in days. +* **[ItemsAPI](https://www.itemsapi.com/)**: Search backend for web and mobile applications built on Express and Elasticsearch. +* **[KeystoneJS](http://keystonejs.com/)**: Website and API Application Framework / CMS with an auto-generated React.js Admin UI. +* **[Poet](http://jsantell.github.io/poet)**: Lightweight Markdown Blog Engine with instant pagination, tag and category views. +* **[Kraken](http://krakenjs.com/)**: Secure and scalable layer that extends Express by providing structure and convention. +* **[LoopBack](http://loopback.io)**: Highly-extensible, open-source Node.js framework for quickly creating dynamic end-to-end REST APIs. +* **[Sails](http://sailsjs.org/)**: MVC framework for Node.js for building practical, production-ready apps. +* **[Hydra-Express](https://github.com/flywheelsports/fwsp-hydra-express)**: Hydra-Express is a light-weight library which facilitates building Node.js Microservices using ExpressJS. +* **[Blueprint](http://github.com/onehilltech/blueprint)**: a SOLID framework for building APIs and backend services +* **[Locomotive](http://locomotivejs.org/)**: Powerful MVC web framework for Node.js from the maker of Passport.js +* **[graphql-yoga](https://github.com/graphcool/graphql-yoga)**: Fully-featured, yet simple and lightweight GraphQL server +* **[Express Gateway](https://express-gateway.io)**: Fully-featured and extensible API Gateway using Express as foundation +* **[Dinoloop](https://github.com/ParallelTask/dinoloop)**: Rest API Application Framework powered by typescript with dependency injection +* **[Kites](https://kites.nodejs.vn/)**: Template-based Web Application Framework +* **[FoalTS](https://foalts.org/)**: Elegant and all-inclusive Node.Js web framework based on TypeScript. +* **[NestJs](https://github.com/nestjs/nest)**: A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications on top of TypeScript & JavaScript (ES6, ES7, ES8) +* **[Expressive Tea](https://github.com/Zero-OneiT/expresive-tea)**: A Small framework for building modulable, clean, fast and descriptive server-side applications with Typescript and Express out of the box. + +Expressjs Code. + +const express = require('express') +const app = express() +const port = 3000 + +app.get('/', (req, res) => { + res.send('Hello World!') +}) + +app.listen(port, () => { + console.log(`Example app listening on port ${port}`) +}) + + + + + + + + + + + + + + + + + + + + + + diff --git a/README.md b/README.md deleted file mode 100644 index a7afc49..0000000 --- a/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# Hello GitHub Actions - -_Create and run a GitHub Actions workflow._ - -## Welcome - -Automation is key for repetitive tasks like testing, scanning, review, and deployment processes, and [GitHub Actions](https://docs.github.com/actions) is the best way to streamline that workflow. - -- **Who is this for**: Developers, DevOps engineers, Security engineers -- **What you'll learn**: How to create GitHub Actions workflows, how to run them, and how to use them to automate tasks. -- **What you'll build**: An Actions workflow that will comment on a pull request when it is created. -- **Prerequisites**: [Introduction to GitHub](https://github.com/skills/introduction-to-github) -- **How long**: This exercise can be finished in less than 30min. - -In this exercise, you will: - -1. Create a workflow file -1. Add a job -1. Add a run step -1. See the workflow run -1. Merge your pull request - -### How to start this exercise - -Simply copy the exercise to your account, then give your favorite Octocat (Mona) **about 20 seconds** to prepare the first lesson, then **refresh the page**. - -[![](https://img.shields.io/badge/Copy%20Exercise-%E2%86%92-1f883d?style=for-the-badge&logo=github&labelColor=197935)](https://github.com/new?template_owner=skills&template_name=hello-github-actions&owner=%40me&name=skills-hello-github-actions&description=Exercise:+Create+and+run+a+GitHub+Actions+Workflow&visibility=public) - -
-Having trouble? 🤷
- -When copying the exercise, we recommend the following settings: - -- For owner, choose your personal account or an organization to host the repository. - -- We recommend creating a public repository, since private repositories will use Actions minutes. - -If the exercise isn't ready in 20 seconds, please check the [Actions](../../actions) tab. - -- Check to see if a job is running. Sometimes it simply takes a bit longer. - -- If the page shows a failed job, please submit an issue. Nice, you found a bug! 🐛 - -
- ---- - -© 2025 GitHub • [Code of Conduct](https://www.contributor-covenant.org/version/2/1/code_of_conduct/code_of_conduct.md) • [MIT License](https://gh.io/mit)