Node.js server without a framework - Learn web development

Node.js server without a framework
==================================

 This article provides a simple static file server built with pure Node.js without the use of a framework.
 The current state of Node.js is such that almost everything we needed is provided by the inbuilt APIs and just a few lines of code.

Example
-------

A simple static file server built with Node.js:

```js
import \* as fs from "node:fs";
import \* as http from "node:http";
import \* as path from "node:path";

const PORT = 8000;

const MIME\_TYPES = {
  default: "application/octet-stream",
  html: "text/html; charset=UTF-8",
  js: "application/javascript",
  css: "text/css",
  png: "image/png",
  jpg: "image/jpg",
  gif: "image/gif",
  ico: "image/x-icon",
  svg: "image/svg+xml",
};

const STATIC\_PATH = path.join(process.cwd(), "./static");

const toBool = [() => true, () => false];

const prepareFile = async (url) => {
  const paths = [STATIC\_PATH, url];
  if (url.endsWith("/")) paths.push("index.html");
  const filePath = path.join(...paths);
  const pathTraversal = !filePath.startsWith(STATIC\_PATH);
  const exists = await fs.promises.access(filePath).then(...toBool);
  const found = !pathTraversal && exists;
  const streamPath = found ? filePath : STATIC\_PATH + "/404.html";
  const ext = path.extname(streamPath).substring(1).toLowerCase();
  const stream = fs.createReadStream(streamPath);
  return { found, ext, stream };
};

http
  .createServer(async (req, res) => {
    const file = await prepareFile(req.url);
    const statusCode = file.found ? 200 : 404;
    const mimeType = MIME\_TYPES[file.ext] || MIME\_TYPES.default;
    res.writeHead(statusCode, { "Content-Type": mimeType });
    file.stream.pipe(res);
    console.log(`${req.method} ${req.url} ${statusCode}`);
  })
  .listen(PORT);

console.log(`Server running at http://127.0.0.1:${PORT}/`);
```

### Breakdown

The following lines import internal Node.js modules.

```js
import \* as fs from "node:fs";
import \* as http from "node:http";
import \* as path from "node:path";
```

Next we have a function for creating the server. `https.createServer` returns a `Server` object, which we can start up by listening on `PORT`.

```js
http
  .createServer((req, res) => {
    /\* handle http requests \*/
  })
  .listen(PORT);

console.log(`Server running at http://127.0.0.1:${PORT}/`);
```

 The asynchronous function `prepareFile` returns the structure: `{ found: boolean , ext: string, stream: ReadableStream }`.
 If the file can be served (the server process has access and no path-traversal vulnerability is found), we will return the HTTP status of `200` as a `statusCode` indicating success (otherwise we return `HTTP 404`).
 Note that other status codes can be found in `http.STATUS_CODES`.
 With `404` status we will return content of `'/404.html'` file.

The extension of the file being requested will be parsed and lower-cased. After that we will search `MIME_TYPES` collection for the right MIME types. If no matches are found, we use the `application/octet-stream` as the default type.

Finally, if there are no errors, we send the requested file. The `file.stream` will contain a `Readable` stream that will be piped into `res` (an instance of the `Writable` stream).

```js
res.writeHead(statusCode, { "Content-Type": mimeType });
file.stream.pipe(res);
```


Django Web Framework (Python) - Learn web development

Django Web Framework (Python)
=============================

Django is an extremely popular and fully featured server-side web framework, written in Python. This module shows you why Django is one of the most popular web server frameworks, how to set up a development environment, and how to start using it to create your own web applications.

Prerequisites
-------------

Before starting this module you don't need to have any knowledge of Django. Ideally, you would need to understand what server-side web programming and web frameworks are by reading the topics in our Server-side website programming first steps module.

A general knowledge of programming concepts and Python is recommended, but is not essential to understanding the core concepts.

**Note:** Python is one of the easiest programming languages for novices to read and understand. That said, if you want to understand this module better, there are numerous free books and tutorials available on the internet to help you out (new programmers might want to check out the Python for Non Programmers page on the python.org wiki).

Guides
------

Django introduction

In this first Django article we answer the question "What is Django?" and give you an overview of what makes this web framework special. We'll outline the main features, including some advanced functionality that we won't have time to cover in detail in this module. We'll also show you some of the main building blocks of a Django application, to give you an idea of what it can do before you set it up and start playing.

Setting up a Django development environment

Now that you know what Django is for, we'll show you how to set up and test a Django development environment on Windows, Linux (Ubuntu), and macOS — whatever common operating system you are using, this article should give you what you need to be able to start developing Django apps.

Django Tutorial: The Local Library website

The first article in our practical tutorial series explains what you'll learn, and provides an overview of the "local library" — an example website we'll be working through and evolving in subsequent articles.

Django Tutorial Part 2: Creating a skeleton website

This article shows how you can create a "skeleton" website project, which you can then go on to populate with site-specific settings, URLs, models, views, and templates.

Django Tutorial Part 3: Using models

This article shows how to define models for the *LocalLibrary* website — models represent the data structures we want to store our app's data in, and also allow Django to store data in a database for us (and modify it later on). It explains what a model is, how it is declared, and some of the main field types. It also briefly shows a few of the main ways you can access model data.

Django Tutorial Part 4: Django admin site

Now that we've created models for the *LocalLibrary* website, we'll use the Django Admin site to add some "real" book data. First, we'll show you how to register the models with the admin site, then we'll show you how to login and create some data. At the end, we show some ways in which you can further improve the presentation of the admin site.

Django Tutorial Part 5: Creating our home page

We're now ready to add the code to display our first full page — a home page for the *LocalLibrary* that shows how many records we have of each model type, and provides sidebar navigation links to our other pages. Along the way we'll gain practical experience in writing basic URL maps and views, getting records from the database, and using templates.

Django Tutorial Part 6: Generic list and detail views

This tutorial extends our *LocalLibrary* website, adding list and detail pages for books and authors. Here we'll learn about generic class-based views, and show how they can reduce the amount of code you have to write for common use cases. We'll also go into URL handling in greater detail, showing how to perform basic pattern matching.

Django Tutorial Part 7: Sessions framework

This tutorial extends our *LocalLibrary* website, adding a session-based visit-counter to the home page. This is a relatively simple example, but it does show how you can use the session framework to provide persistent behavior for anonymous users on your own sites.

Django Tutorial Part 8: User authentication and permissions

In this tutorial we'll show you how to allow users to login to your site with their own accounts, and how to control what they can do and see based on whether or not they are logged in and their *permissions*. As part of this demonstration, we'll extend the *LocalLibrary* website, adding login and logout pages, and user- and staff-specific pages for viewing books that have been borrowed.

Django Tutorial Part 9: Working with forms

In this tutorial we'll show you how to work with HTML Forms in Django, and in particular the easiest way to write forms to create, update and delete model instances. As part of this demonstration, we'll extend the *LocalLibrary* website so that librarians can renew books, and create, update, and delete authors using our own forms (rather than using the admin application).

Django Tutorial Part 10: Testing a Django web application

As websites grow they become harder to test manually — not only is there more to test, but, as the interactions between components become more complex, a small change in one area can require many additional tests to verify its impact on other areas. One way to mitigate these problems is to write automated tests, which can easily and reliably be run every time you make a change. This tutorial shows how to automate *unit testing* of your website using Django's test framework.

Django Tutorial Part 11: Deploying Django to production

Now you've created (and tested) an awesome *LocalLibrary* website, you're going to want to install it on a public web server so that it can be accessed by library staff and members over the internet. This article provides an overview of how you might go about finding a host to deploy your website, and what you need to do in order to get your site ready for production.

Django web application security

Protecting user data is an essential part of any website design. We previously explained some of the more common security threats in the article Web security — this article provides a practical demonstration of how Django's built-in protections handle such threats.

Assessments
-----------

The following assessment will test your understanding of how to create a website using Django, as described in the guides listed above.

DIY Django mini blog

In this assessment you'll use some of the knowledge you've learned from this module to create your own blog.


Server-side website programming first steps - Learn web development

Server-side website programming first steps
===========================================

In this module, we answer a few fundamental questions about server-side programming such as "What is it?", "How does it differ from client-side programming?", and "Why is it so useful?". We also provide an overview of some of the most popular server-side web frameworks, along with guidance on how to select the most suitable framework for creating your first project. Finally, we provide a high-level introductory article about web server security.

Prerequisites
-------------

Before starting this module, you don't need to have any knowledge of server-side website programming or any other type of programming.

However, you should understand something about the workings of websites and web servers. For that purpose, this is our recommended reading:

* What is a web server?
* What software do I need to build a website?
* How do you upload files to a web server?

With the basic understanding that you gain from this preparation, you'll be ready to work your way through the modules in this section.

Guides
------

Introduction to the server-side

Welcome to the MDN beginner's server-side programming course! The first article examines server-side programming from a high level, answering questions such as "What is it?", "How does it differ from client-side programming?", and "Why it is so useful?". After reading this, you will understand the additional capabilities available to websites through server-side coding.

Client-Server overview

Now that you know the purpose and potential benefits of server-side programming, we're going to examine what happens when a server receives a "dynamic request" from a browser. As most websites' server-side code handles requests and responses in a similar way, this will help you understand what you need to do when writing your own code.

Server-side web frameworks

The previous article explained what a server-side web application needs to do to respond to web browser requests. This article explains how web frameworks can simplify these tasks, and helps you choose the right framework for your first server-side web application.

Website security

Website security requires vigilance in all aspects of building and operating a site. This introductory article helps you understand the first important steps you can take to protect your web application against the most common threats.

**Note:** This topic deals with server-side frameworks, and how to use them to create websites. If you are looking for information on client-side JavaScript frameworks, see Understanding client-side JavaScript frameworks.

Assessments
-----------

This "first steps" module doesn't have any assessment because we haven't yet shown you any code. At this point, you should have a general understanding of the functionality you can deliver with server-side programming, and you have made a decision about what server-side web framework you will use to create your first server-side application.


Express web framework (Node.js/JavaScript) - Learn web development

Express web framework (Node.js/JavaScript)
==========================================

Express is a popular unopinionated web framework, written in JavaScript and hosted within the Node.js runtime environment. This module explains some of the key benefits of the framework, how to set up your development environment and how to perform common web development and deployment tasks.

Prerequisites
-------------

Before starting this module you will need to understand what server-side web programming and web frameworks are, ideally by reading the topics in our Server-side website programming first steps module. A general knowledge of programming concepts and JavaScript is highly recommended, but not essential to understanding the core concepts.

**Note:** This website has many useful resources for learning JavaScript *in the context of client-side development*: JavaScript, JavaScript Guide, JavaScript Basics, JavaScript (learning). The core JavaScript language and concepts are the same for server-side development on Node.js and this material will be relevant. Node.js offers additional APIs for supporting functionality that is useful in browserless environments (e.g., to create HTTP servers and access the file system), but does not support JavaScript APIs for working with the browser and DOM.

This guide will provide some information about working with Node.js and Express, and there are numerous other excellent resources on the Internet and in books — some of these linked from How do I get started with Node.js (StackOverflow) and What are the best resources for learning Node.js? (Quora).

Guides
------

Express/Node introduction

In this first Express article we answer the questions "What is Node?" and "What is Express?" and give you an overview of what makes the Express web framework special. We'll outline the main features and show you some of the main building blocks of an Express application (although at this point you won't yet have a development environment in which to test it).

Setting up a Node (Express) development environment

Now that you know what Express is for, we'll show you how to set up and test a Node/Express development environment on Windows, Linux (Ubuntu), and macOS. Whatever common operating system you are using, this article should give you what you need to be able to start developing Express apps.

Express Tutorial: The Local Library website

The first article in our practical tutorial series explains what you'll learn and provides an overview of the "local library" example website we'll be working through and evolving in subsequent articles.

Express Tutorial Part 2: Creating a skeleton website

This article shows how you can create a "skeleton" website project, which you can then go on to populate with site-specific routes, templates/views, and databases.

Express Tutorial Part 3: Using a Database (with Mongoose)

This article briefly introduces databases for Node/Express. It then goes on to show how we can use Mongoose to provide database access for the *LocalLibrary* website. It explains how object schema and models are declared, the main field types, and basic validation. It also briefly shows a few of the main ways you can access model data.

Express Tutorial Part 4: Routes and controllers

In this tutorial we'll set up routes (URL handling code) with "dummy" handler functions for all the resource endpoints that we'll eventually need in the *LocalLibrary* website. On completion, we'll have a modular structure for our route handling code, that we can extend with real handler functions in the following articles. We'll also have a really good understanding of how to create modular routes using Express.

Express Tutorial Part 5: Displaying library data

We're now ready to add the pages that display the *LocalLibrary* website books and other data. The pages will include a home page that shows how many records we have of each model type and list and detail pages for all of our models. Along the way, we'll gain practical experience in getting records from the database and using templates.

Express Tutorial Part 6: Working with forms

In this tutorial we'll show you how to work with HTML Forms in Express, using Pug, and in particular how to write forms to create, update, and delete documents from the database.

Express Tutorial Part 7: Deploying to production

Now you've created an awesome *LocalLibrary* website, you're going to want to install it on a public web server so that it can be accessed by library staff and members over the Internet. This article provides an overview of how you might go about finding a host to deploy your website, and what you need to do in order to get your site ready for production.

Adding more tutorials
---------------------

All existing tutorials are listed above, but if you would like to extend this module, some other interesting topics to cover include:

* Using sessions.
* User authentication.
* User authorization and permissions.
* Testing an Express web application.
* Web security for Express web applications.

An assessment for the module would also make a wonderful addition!


Apache Configuration: .htaccess - Learn web development

Apache Configuration: .htaccess
===============================

Apache .htaccess files allow users to configure directories of the web server they control without modifying the main configuration file.

While this is useful it's important to note that using `.htaccess` files slows down Apache, so, if you have access to the main server configuration file (which is usually called `httpd.conf`), you should add this logic there under a `Directory` block.

See .htaccess in the Apache HTTPD documentation site for more details about what .htaccess files can do.

The remainder of this document will discuss different configuration options you can add to `.htaccess` and what they do.

Most of the following blocks use the IfModule directive to only execute the instructions inside the block if the corresponding module was properly configured and the server loaded it. This way we save our server from crashing if the module wasn't loaded.

Redirects
---------

There are times when we need to tell users that a resource has moved, either temporarily or permanently. This is what we use `Redirect` and `RedirectMatch` for.

```apacheconf
<IfModule mod\_alias.c>
  # Redirect to a URL on a different host
  Redirect "/service" "http://foo2.example.com/service"

  # Redirect to a URL on the same host
  Redirect "/one" "/two"

  # Equivalent redirect to URL on the same host
  Redirect temp "/one" "/two"

  # Permanent redirect to a URL on the same host
  Redirect permanent "/three" "/four"

  # Redirect to an external URL
  # Using regular expressions and RedirectMatch
  RedirectMatch "^/oldfile\.html/?$" "http://example.com/newfile.php"
</IfModule>
```

The possible values for the first parameter are listed below. If the first parameter is not included, it defaults to `temp`.

permanent

Returns a permanent redirect status (301) indicating that the resource has moved permanently.

temp

Returns a temporary redirect status (302). **This is the default**.

seeother

Returns a "See Other" status (303) indicating that the resource has been replaced.

gone

Returns a "Gone" status (410) indicating that the resource has been permanently removed. When this status is used the *URL* argument should be omitted.

Cross-origin resources
----------------------

The first set of directives control CORS (Cross-Origin Resource Sharing) access to resources from the server. CORS is an HTTP-header based mechanism that allows a server to indicate the external origins (domain, protocol, or port) which a browser should permit loading of resources.

For security reasons, browsers restrict cross-origin HTTP requests initiated from scripts. For example, XMLHttpRequest and the Fetch API follow the same-origin policy. A web application using those APIs can only request resources from the same origin the application was loaded from unless the response from other origins includes the appropriate CORS headers.

### General CORS access

This directive will add the CORS header for all resources in the directory from any website.

```apacheconf
<IfModule mod\_headers.c>
  Header set Access-Control-Allow-Origin "\*"
</IfModule>
```

Unless you override the directive later in the configuration or in the configuration of a directory below where you set this one, every request from external servers will be honored, which is unlikely to be what you want.

One alternative is to explicitly state what domains have access to the content of your site. In the example below, we restrict access to a subdomain of our main site (example.com). This is more secure and, likely, what you intended to do.

```apacheconf
<IfModule mod\_headers.c>
  Header set Access-Control-Allow-Origin "subdomain.example.com"
</IfModule>
```

### Cross-origin images

As reported in the Chromium Blog and documented in Allowing cross-origin use of images and canvas can lead to fingerprinting attacks.

To mitigate the possibility of these attacks, you should use the `crossorigin` attribute in the images you request and the code snippet below in your `.htaccess` to set the CORS header from the server.

```apacheconf
<IfModule mod\_setenvif.c>
  <IfModule mod\_headers.c>
    <FilesMatch "\.(bmp|cur|gif|ico|jpe?g|a?png|svgz?|webp|heic|heif|avif)$">
      SetEnvIf Origin ":" IS_CORS
      Header set Access-Control-Allow-Origin "\*" env=*IS_CORS*
    </FilesMatch>
  </IfModule>
</IfModule>
```

Google Chrome's Google Fonts troubleshooting guide tells us that, while Google Fonts may send the CORS header with every response, some proxy servers may strip it before the browser can use it to render the font.

```apacheconf
<IfModule mod\_headers.c>
  <FilesMatch "\.(eot|otf|tt[cf]|woff2?)$">
    Header set Access-Control-Allow-Origin "\*"
  </FilesMatch>
</IfModule>
```

### Cross-origin resource timing

The Resource Timing Level 1 specification defines an interface for web applications to access the complete timing information for resources in a document.

The Timing-Allow-Origin response header specifies origins that are allowed to see values of attributes retrieved via features of the Resource Timing API, which would otherwise be reported as zero due to cross-origin restrictions.

If a resource isn't served with a `Timing-Allow-Origin` or if the header does not include the origin after making the request, some attributes of the `PerformanceResourceTiming` object will be set to zero.

```apacheconf
<IfModule mod\_headers.c>
  Header set Timing-Allow-Origin: "\*"
</IfModule>
```

Custom error pages/messages
---------------------------

Apache allows you to provide custom error pages for users depending on the type of error they receive.

The error pages are presented as URLs. These URLs can begin with a slash (/) for local web paths (relative to the DocumentRoot) or be a full URL that the client can resolve.

See the ErrorDocument Directive documentation on the HTTPD documentation site for more information.

```apacheconf
ErrorDocument 500 /errors/500.html
ErrorDocument 404 /errors/400.html
ErrorDocument 401 https://example.com/subscription_info.html
ErrorDocument 403 "Sorry, can't allow you access today."
```

Error prevention
----------------

This setting affects how MultiViews work for the directory the configuration applies to.

The effect of `MultiViews` is as follows: if the server receives a request for /some/dir/foo, if /some/dir has `MultiViews` enabled, and /some/dir/foo does not exist, then the server reads the directory looking for files named foo.\*, and effectively fakes up a type map which names all those files, assigning them the same media types and content-encodings it would have if the client had asked for one of them by name. It then chooses the best match to the client's requirements.

The setting disables `MultiViews` for the directory this configuration applies to and prevents Apache from returning a 404 error as the result of a rewrite when the directory with the same name does not exist

```apacheconf
Options -MultiViews
```

Media types and character encodings
-----------------------------------

Apache uses mod\_mime to assign content metadata to the content selected for an HTTP response by mapping patterns in the URI or filenames to the metadata values.

For example, the filename extensions of content files often define the content's Internet media type, language, character set, and content encoding. This information is sent in HTTP messages containing that content and used in content negotiation when selecting alternatives, such that the user's preferences are respected when choosing one of several possible contents to serve.

**Changing the metadata for a file does not change the value of the Last-Modified header. Thus, previously cached copies may still be used by a client or proxy, with the previous headers. If you change the metadata (language, content type, character set, or encoding), you may need to 'touch' affected files (updating their last modified date) to ensure all visitors receive the corrected content headers.**

### Serve resources with the proper media types (a.k.a. MIME types)

Associates media types with one or more extensions to make sure the resources will be served appropriately.

Servers should use `text/javascript` for JavaScript resources as indicated in the HTML specification

```apacheconf
<IfModule mod\_expires.c>
  # Data interchange
    AddType application/atom+xml      atom
    AddType application/json          json map topojson
    AddType application/ld+json       jsonld
    AddType application/rss+xml       rss
    AddType application/geo+json      geojson
    AddType application/rdf+xml       rdf
    AddType application/xml           xml
  # JavaScript
    AddType text/javascript           js mjs
  # Manifest files
    AddType application/manifest+json     webmanifest
    AddType application/x-web-app-manifest+json         webapp
    AddType text/cache-manifest           appcache
  # Media files
    AddType audio/mp4                     f4a f4b m4a
    AddType audio/ogg                     oga ogg opus
    AddType image/bmp                     bmp
    AddType image/svg+xml                 svg svgz
    AddType image/webp                    webp
    AddType video/mp4                     f4v f4p m4v mp4
    AddType video/ogg                     ogv
    AddType video/webm                    webm
    AddType image/x-icon    cur ico
  # HEIF Images
    AddType image/heic                    heic
    AddType image/heif                    heif
  # HEIF Image Sequence
    AddType image/heics                   heics
    AddType image/heifs                   heifs
  # AVIF Images
    AddType image/avif                    avif
  # AVIF Image Sequence
    AddType image/avis                    avis
  # WebAssembly
    AddType application/wasm              wasm
  # Web fonts
    AddType font/woff                         woff
    AddType font/woff2                        woff2
    AddType application/vnd.ms-fontobject                eot
    AddType font/ttf                          ttf
    AddType font/collection                   ttc
    AddType font/otf                          otf
  # Other
    AddType application/octet-stream          safariextz
    AddType application/x-bb-appworld         bbaw
    AddType application/x-chrome-extension    crx
    AddType application/x-opera-extension     oex
    AddType application/x-xpinstall           xpi
    AddType text/calendar                     ics
    AddType text/markdown                     markdown md
    AddType text/vcard                        vcard vcf
    AddType text/vnd.rim.location.xloc        xloc
    AddType text/vtt                          vtt
    AddType text/x-component                  htc
</IfModule>
```

Set the default charset attribute
---------------------------------

Every piece of content on the web has a character set. Most, if not all, the content is UTF-8 Unicode.

Use AddDefaultCharset to serve all resources labeled as `text/html` or `text/plain` with the `UTF-8` charset.

```apacheconf
<IfModule mod\_mime.c>
  AddDefaultCharset utf-8
</IfModule>
```

Set the charset for specific media types
----------------------------------------

Serve the following file types with the `charset` parameter set to `UTF-8` using the AddCharset directive available in `mod_mime`.

```apacheconf
<IfModule mod\_mime.c>
  AddCharset utf-8 .appcache \
    .bbaw \
    .css \
    .htc \
    .ics \
    .js \
    .json \
    .manifest \
    .map \
    .markdown \
    .md \
    .mjs \
    .topojson \
    .vtt \
    .vcard \
    .vcf \
    .webmanifest \
    .xloc
</IfModule>
```

`Mod_rewrite` and the `RewriteEngine` directives
------------------------------------------------

mod\_rewrite provides a way to modify incoming URL requests, dynamically, based on regular expression rules. This allows you to map arbitrary URLs onto your internal URL structure in any way you like.

It supports an unlimited number of rules and an unlimited number of attached rule conditions for each rule to provide a really flexible and powerful URL manipulation mechanism. The URL manipulations can depend on various tests: server variables, environment variables, HTTP headers, timestamps, external database lookups, and various other external programs or handlers, can be used to achieve granular URL matching.

### Enable `mod_rewrite`

The basic pattern to enable `mod_rewrite` is a prerequisite for all other tasks that use it.

The required steps are:

1. Turn on the rewrite engine (this is necessary in order for the `RewriteRule` directives to work) as documented in the RewriteEngine documentation
2. Enable the `FollowSymLinks` option if it isn't already. See Core Options documentation
3. If your web host doesn't allow the `FollowSymlinks` option, you need to comment it out or remove it, and then uncomment the `Options +SymLinksIfOwnerMatch` line, but be aware of the performance impact
    * Some cloud hosting services will require you to set `RewriteBase`
    * See Rackspace FAQ and the HTTPD documentation
    * Depending on how your server is set up, you may also need to use the `RewriteOptions` directive to enable some options for the rewrite engine

```apacheconf
<IfModule mod\_rewrite.c>
  RewriteEngine On
  Options +FollowSymlinks
  # Options +SymLinksIfOwnerMatch
  # RewriteBase /
  # RewriteOptions <options>
</IfModule>
```

### Forcing HTTPS

These Rewrite rules will redirect from the `http://` insecure version to the `https://` secure version of the URL as described in the Apache HTTPD wiki.

```apacheconf
<IfModule mod\_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTPS} !=on
  RewriteRule ^/?(.\*) https://%{SERVER\_NAME}/$1 [R,L]
</IfModule>
```

If you're using cPanel AutoSSL or the Let's Encrypt webroot method to create your TLS certificates, it will fail to validate the certificate if validation requests are redirected to HTTPS. Turn on the condition(s) you need.

```apacheconf
<IfModule mod\_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTPS} !=on
  RewriteCond %{REQUEST\_URI} !^/\.well-known/acme-challenge/
  RewriteCond %{REQUEST\_URI} !^/\.well-known/cpanel-dcv/[\w-]+$
  RewriteCond %{REQUEST\_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
  RewriteRule ^ https://%{HTTP\_HOST}%{REQUEST\_URI} [R=301,L]
</IfModule>
```

### Redirecting from `www.` URLs

These directives will rewrite `www.example.com` to `example.com`.

You should not duplicate content in multiple origins (with and without www). This can cause SEO problems (duplicate content), and therefore, you should choose one of the alternatives and redirect the other one. You should also use Canonical URLs to indicate which URL should search engines crawl (if they support the feature).

Set `%{ENV:PROTO}` variable, to allow rewrites to redirect with the appropriate schema automatically (`http` or `https`).

The rule assumes by default that both HTTP and HTTPS environments are available for redirection.

```apacheconf
<IfModule mod\_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTPS} =on
  RewriteRule ^ - [E=PROTO:https]
  RewriteCond %{HTTPS} !=on
  RewriteRule ^ - [E=PROTO:http]

  RewriteCond %{HTTP\_HOST} ^www\.(.+)$ [NC]
  RewriteRule ^ %{ENV:PROTO}://%1%{REQUEST\_URI} [R=301,L]
</IfModule>
```

### Inserting the `www.` at the beginning of URLs

These rules will insert `www.` at the beginning of a URL. It's important to note that you should never make the same content available under two different URLs.

This can cause SEO problems (duplicate content), and therefore, you should choose one of the alternatives and redirect the other one. For search engines that support them, you should use Canonical URLs to indicate which URL should search engines crawl.

Set the `%{ENV:PROTO}` variable, to allow rewrites to redirect with the appropriate schema automatically (`http` or `https`).

The rule assumes by default that both HTTP and HTTPS environments are available for redirection. If your TLS certificate cannot handle one of the domains used during redirection, you should turn the condition on.

The following might not be a good idea if you use "real" subdomains for certain parts of your website.

```apacheconf
<IfModule mod\_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTPS} =on
  RewriteRule ^ - [E=PROTO:https]
  RewriteCond %{HTTPS} !=on
  RewriteRule ^ - [E=PROTO:http]

  RewriteCond %{HTTPS} !=on

  RewriteCond %{HTTP\_HOST} !^www\. [NC]
  RewriteCond %{SERVER\_ADDR} !=127.0.0.1
  RewriteCond %{SERVER\_ADDR} !=::1
  RewriteRule ^ %{ENV:PROTO}://www.%{HTTP\_HOST}%{REQUEST\_URI} [R=301,L]
</IfModule>
```

Frame options
-------------

The example below sends the `X-Frame-Options` response header with DENY as the value, informing browsers not to display the content of the web page in any frame to protect the website against clickjacking.

This might not be the best setting for everyone. You should read about the other two possible values for the `X-Frame-Options` header: `SAMEORIGIN` and `ALLOW-FROM`.

While you could send the `X-Frame-Options` header for all of your website's pages, this has the potential downside that it forbids even any framing of your content (e.g.: when users visit your website using a Google Image Search results page).

Nonetheless, you should ensure that you send the `X-Frame-Options` header for all pages that allow a user to make a state-changing operation (e.g., pages that contain one-click purchase links, checkout, or bank-transfer confirmation pages, pages that make permanent configuration changes, etc.).

```apacheconf
<IfModule mod\_headers.c>
  Header always set X-Frame-Options "DENY" "expr=%{CONTENT\_TYPE} =~ m#text/html#i"
</IfModule>
```

Content Security Policy (CSP)
-----------------------------

CSP (Content Security Policy) mitigates the risk of cross-site scripting and other content-injection attacks by setting a `Content Security Policy` which allows trusted sources of content for your website.

There is no policy that fits all websites, the example below is meant as guidelines for you to modify for your site.

To make your CSP implementation easier, you can use an online CSP header generator. You should also use a validator to make sure your header does what you want it to do.

```apacheconf
<IfModule mod\_headers.c>
  Content-Security-Policy "default-src 'self'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests" "expr=%{CONTENT\_TYPE} =~ m#text\/(html|javascript)|application\/pdf|xml#i"
</IfModule>
```

Directory access
----------------

This directive will prevent access to directories that don't have an index file present in whatever format the server is configured to use, like `index.html`, or `index.php`.

```apacheconf
<IfModule mod\_autoindex.c>
    Options -Indexes
</IfModule>
```

Block access to hidden files and directories
--------------------------------------------

In Macintosh and Linux systems, files that begin with a period are hidden from view but not from access if you know their name and location. These types of files usually contain user preferences or the preserved state of a utility, and can include rather private places like, for example, the `.git` or `.svn` directories.

The `.well-known/` directory represents the standard (RFC 5785) path prefix for "well-known locations" (e.g.: `/.well-known/manifest.json`, `/.well-known/keybase.txt`), and therefore, access to its visible content should not be blocked.

```apacheconf
<IfModule mod\_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST\_URI} "!(^|/)\.well-known/([^./]+./?)+$" [NC]
    RewriteCond %{SCRIPT\_FILENAME} -d [OR]
    RewriteCond %{SCRIPT\_FILENAME} -f
    RewriteRule "(^|/)\." - [F]
</IfModule>
```

Block access to files with sensitive information
------------------------------------------------

Block access to backup and source files that may be left by some text editors and can pose a security risk when anyone has access to them.

Update the `<FilesMatch>` regular expression in the following example to include any files that might end up on your production server and can expose sensitive information about your website. These files may include configuration files or files that contain metadata about the project, among others.

```apacheconf
<IfModule mod\_authz\_core.c>
  <FilesMatch "(^#.\*#|\.(bak|conf|dist|fla|in[ci]|log|orig|psd|sh|sql|sw[op])|~)$">
    Require all denied
  </FilesMatch>
</IfModule>
```

HTTP Strict Transport Security (HSTS)
-------------------------------------

If a user types `example.com` in their browser, even if the server redirects them to the secure version of the website, that still leaves a window of opportunity (the initial HTTP connection) for an attacker to downgrade or redirect the request.

The following header ensures that a browser only connects to your server via HTTPS, regardless of what the users type in the browser's address bar.

Be aware that Strict Transport Security is not revokable, and you must ensure being able to serve the site over HTTPS for as long as you've specified in the `max-age` directive. If you don't have a valid TLS connection anymore (e.g., due to an expired TLS certificate), your visitors will see an error message even when attempting to connect over HTTP.

```apacheconf
<IfModule mod\_headers.c>
  # Header always set
  Strict-Transport-Security "max-age=16070400; includeSubDomains" "expr=%{HTTPS} == 'on'"
  # (1) Enable your site for HSTS preload inclusion.
  # Header always set
  Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" "expr=%{HTTPS} == 'on'"
</IfModule>
```

Prevent some browsers from MIME-sniffing the response
-----------------------------------------------------

1. Restricts all fetches by default to the origin of the current website by setting the `default-src` directive to `'self'` - which acts as a fallback to all Fetch directives.
    * This is convenient as you do not have to specify all Fetch directives that apply to your site, for example: `connect-src 'self'; font-src 'self'; script-src 'self'; style-src 'self'`, etc
    * This restriction also means that you must explicitly define from which site(s) your website is allowed to load resources from. Otherwise, it will be restricted to the same origin as the page making the request
2. Disallows the `<base>` element on the website. This is to prevent attackers from changing the locations of resources loaded from relative URLs
    * If you want to use the `<base>` element, then use `base-uri 'self'` instead
3. Only allows form submissions are from the current origin with: `form-action 'self'`
4. Prevents all websites (including your own) from embedding your webpages within e.g. the `<iframe>` or `<object>` element by setting: `frame-ancestors 'none'`.
    * The `frame-ancestors` directive helps avoid clickjacking attacks and is similar to the `X-Frame-Options` header
    * Browsers that support the CSP header will ignore `X-Frame-Options` if `frame-ancestors` is also specified
5. Forces the browser to treat all the resources that are served over HTTP as if they were loaded securely over HTTPS by setting the `upgrade-insecure-requests` directive
    * **`upgrade-insecure-requests` does not ensure HTTPS for the top-level navigation. If you want to force the website itself to be loaded over HTTPS you must include the `Strict-Transport-Security` header**
6. Includes the `Content-Security-Policy` header in all responses that are able to execute scripting. This includes the commonly used file types: HTML, XML and PDF documents. Although JavaScript files can not execute scripts in a "browsing context", they are included to target web workers

Some older browsers would try and guess the content type of a resource, even when it isn't properly set up on the server configuration. This reduces exposure to drive-by download attacks and cross-origin data leaks.

```apacheconf
<IfModule mod\_headers.c>
    Header always set X-Content-Type-Options "nosniff"
</IfModule>
```

Referrer policy
---------------

We include the `Referrer-Policy` header in responses for resources that are able to request (or navigate to) other resources.

This includes commonly used resource types: HTML, CSS, XML/SVG, PDF documents, scripts, and workers.

To prevent referrer leakage entirely, specify the `no-referrer` value instead. Note that the effect could negatively impact analytics tools.

Use services like the ones below to check your `Referrer-Policy`:

* securityheaders.com
* Mozilla Observatory

```apacheconf
<IfModule mod\_headers.c>
  Header always set Referrer-Policy "strict-origin-when-cross-origin" "expr=%{CONTENT\_TYPE} =~ m#text\/(css|html|javascript)|application\/pdf|xml#i"
</IfModule>
```

Disable `TRACE` HTTP Method
---------------------------

The TRACE method, while seemingly harmless, can be successfully leveraged in some scenarios to steal legitimate users' credentials. See A Cross-Site Tracing (XST) attack and OWASP Web Security Testing Guide

Modern browsers now prevent TRACE requests made via JavaScript, however, other ways of sending TRACE requests with browsers have been discovered, such as using Java.

If you have access to the main server configuration file, use the `TraceEnable` directive instead.

```apacheconf
<IfModule mod\_rewrite.c>
  RewriteEngine On
  RewriteCond %{REQUEST\_METHOD} ^TRACE [NC]
  RewriteRule .* - [R=405,L]
</IfModule>
```

Remove the `X-Powered-By` response header
-----------------------------------------

Some frameworks like PHP and ASP.NET set an `X-Powered-By` header that contains information about them (e.g., their name, version number)

This header doesn't provide any value, and in some cases, the information it provides can expose vulnerabilities

```apacheconf
<IfModule mod\_headers.c>
  Header unset X-Powered-By
  Header always unset X-Powered-By
</IfModule>
```

If you can, you should disable the `X-Powered-By` header from the language/framework level (e.g.: for PHP, you can do that by setting the following in `php.ini`.

```ini
expose\_php = off;
```

Remove Apache-generated server information footer
-------------------------------------------------

Prevent Apache from adding a trailing footer line containing information about the server to the server-generated documents (e.g., error messages, directory listings, etc.). See the `ServerSignature` directive documentation for more information on what the server signature provides and the `ServerTokens` directive for information about configuring the information provided in the signature.

```apacheconf
ServerSignature Off
```

Fix broken `AcceptEncoding` headers
-----------------------------------

Some proxies and security software mangle or strip the `Accept-Encoding` HTTP header. See Pushing Beyond Gzipping for a more detailed explanation.

```apacheconf
<IfModule mod\_deflate.c>
  <IfModule mod\_setenvif.c>
    <IfModule mod\_headers.c>
      SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s\*,?\s\*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
      RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
    </IfModule>
  </IfModule>
</IfModule>
```

Compress media types
--------------------

Compress all output labeled with one of the following media types using the AddOutputFilterByType Directive.

```apacheconf
<IfModule mod\_deflate.c>
  <IfModule mod\_filter.c>
    AddOutputFilterByType DEFLATE "application/atom+xml" \
      "application/javascript" \
      "application/json" \
      "application/ld+json" \
      "application/manifest+json" \
      "application/rdf+xml" \
      "application/rss+xml" \
      "application/schema+json" \
      "application/geo+json" \
      "application/vnd.ms-fontobject" \
      "application/wasm" \
      "application/x-font-ttf" \
      "application/x-javascript" \
      "application/x-web-app-manifest+json" \
      "application/xhtml+xml" \
      "application/xml" \
      "font/eot" \
      "font/opentype" \
      "font/otf" \
      "font/ttf" \
      "image/bmp" \
      "image/svg+xml" \
      "image/vnd.microsoft.icon" \
      "text/cache-manifest" \
      "text/calendar" \
      "text/css" \
      "text/html" \
      "text/javascript" \
      "text/plain" \
      "text/markdown" \
      "text/vcard" \
      "text/vnd.rim.location.xloc" \
      "text/vtt" \
      "text/x-component" \
      "text/x-cross-domain-policy" \
      "text/xml"
  </IfModule>
</IfModule>
```

Map extensions to media types
-----------------------------

Map the following filename extensions to the specified encoding type using AddEncoding so Apache can serve the file types with the appropriate `Content-Encoding` response header (this will NOT make Apache compress them!). If these file types were served without an appropriate `Content-Encoding` response header, client applications (e.g., browsers) wouldn't know that they first need to uncompress the response, and thus, wouldn't be able to understand the content.

```apacheconf
<IfModule mod\_deflate.c>
  <IfModule mod\_mime.c>
    AddEncoding gzip svgz
  </IfModule>
</IfModule>
```

Cache expiration
----------------

Serve resources with a far-future expiration date using the mod\_expires module, and Cache-Control and Expires headers.

```apacheconf
<IfModule mod\_expires.c>
    ExpiresActive on
    ExpiresDefault                                      "access plus 1 month"

  # CSS
    ExpiresByType text/css                              "access plus 1 year"
  # Data interchange
    ExpiresByType application/atom+xml                  "access plus 1 hour"
    ExpiresByType application/rdf+xml                   "access plus 1 hour"
    ExpiresByType application/rss+xml                   "access plus 1 hour"
    ExpiresByType application/json                      "access plus 0 seconds"
    ExpiresByType application/ld+json                   "access plus 0 seconds"
    ExpiresByType application/schema+json               "access plus 0 seconds"
    ExpiresByType application/geo+json                  "access plus 0 seconds"
    ExpiresByType application/xml                       "access plus 0 seconds"
    ExpiresByType text/calendar                         "access plus 0 seconds"
    ExpiresByType text/xml                              "access plus 0 seconds"
  # Favicon (cannot be renamed!) and cursor images
    ExpiresByType image/vnd.microsoft.icon              "access plus 1 week"
    ExpiresByType image/x-icon                          "access plus 1 week"
  # HTML
    ExpiresByType text/html                             "access plus 0 seconds"
  # JavaScript
    ExpiresByType text/javascript                       "access plus 1 year"
  # Manifest files
    ExpiresByType application/manifest+json             "access plus 1 week"
    ExpiresByType application/x-web-app-manifest+json   "access plus 0 seconds"
    ExpiresByType text/cache-manifest                   "access plus 0 seconds"
  # Markdown
    ExpiresByType text/markdown                         "access plus 0 seconds"
  # Media files
    ExpiresByType audio/ogg                             "access plus 1 month"
    ExpiresByType image/bmp                             "access plus 1 month"
    ExpiresByType image/gif                             "access plus 1 month"
    ExpiresByType image/jpeg                            "access plus 1 month"
    ExpiresByType image/svg+xml                         "access plus 1 month"
    ExpiresByType image/webp                            "access plus 1 month"
    # PNG and animated PNG
    ExpiresByType image/apng                            "access plus 1 month"
    ExpiresByType image/png                             "access plus 1 month"
    # HEIF Images
    ExpiresByType image/heic                            "access plus 1 month"
    ExpiresByType image/heif                            "access plus 1 month"
    # HEIF Image Sequence
    ExpiresByType image/heics                           "access plus 1 month"
    ExpiresByType image/heifs                           "access plus 1 month"
    # AVIF Images
    ExpiresByType image/avif                            "access plus 1 month"
    # AVIF Image Sequence
    ExpiresByType image/avis                            "access plus 1 month"
    ExpiresByType video/mp4                             "access plus 1 month"
    ExpiresByType video/ogg                             "access plus 1 month"
    ExpiresByType video/webm                            "access plus 1 month"
  # WebAssembly
    ExpiresByType application/wasm                      "access plus 1 year"
  # Web fonts
    # Collection
    ExpiresByType font/collection                       "access plus 1 month"
    # Embedded OpenType (EOT)
    ExpiresByType application/vnd.ms-fontobject         "access plus 1 month"
    ExpiresByType font/eot                              "access plus 1 month"
    # OpenType
    ExpiresByType font/opentype                         "access plus 1 month"
    ExpiresByType font/otf                              "access plus 1 month"
    # TrueType
    ExpiresByType application/x-font-ttf                "access plus 1 month"
    ExpiresByType font/ttf                              "access plus 1 month"
    # Web Open Font Format (WOFF) 1.0
    ExpiresByType application/font-woff                 "access plus 1 month"
    ExpiresByType application/x-font-woff               "access plus 1 month"
    ExpiresByType font/woff                             "access plus 1 month"
    # Web Open Font Format (WOFF) 2.0
    ExpiresByType application/font-woff2                "access plus 1 month"
    ExpiresByType font/woff2                            "access plus 1 month"
  # Other
    ExpiresByType text/x-cross-domain-policy            "access plus 1 week"
</IfModule>
```


Express/Node introduction - Learn web development

Express/Node introduction
=========================

* Overview: Express Nodejs
* Next

In this first Express article we answer the questions "What is Node?" and "What is Express?", and give you an overview of what makes the Express web framework special. We'll outline the main features, and show you some of the main building blocks of an Express application (although at this point you won't yet have a development environment in which to test it).

|  |  |
| --- | --- |
| Prerequisites: | A general understanding of server-side website programming, and in particular the mechanics of client-server interactions in websites. |
| Objective: | To gain familiarity with what Express is and how it fits in with Node, what functionality it provides, and the main building blocks of an Express application. |

Introducing Node
----------------

Node (or more formally *Node.js*) is an open-source, cross-platform runtime environment that allows developers to create all kinds of server-side tools and applications in JavaScript.
 The runtime is intended for use outside of a browser context (i.e. running directly on a computer or server OS). As such, the environment omits browser-specific JavaScript APIs and adds support for more traditional OS APIs including HTTP and file system libraries.

From a web server development perspective Node has a number of benefits:

* Great performance! Node was designed to optimize throughput and scalability in web applications and is a good solution for many common web-development problems (e.g. real-time web applications).
* Code is written in "plain old JavaScript", which means that less time is spent dealing with "context shift" between languages when you're writing both client-side and server-side code.
* JavaScript is a relatively new programming language and benefits from improvements in language design when compared to other traditional web-server languages (e.g. Python, PHP, etc.) Many other new and popular languages compile/convert into JavaScript so you can also use TypeScript, CoffeeScript, ClojureScript, Scala, LiveScript, etc.
* The node package manager (npm) provides access to hundreds of thousands of reusable packages. It also has best-in-class dependency resolution and can also be used to automate most of the build toolchain.
* Node.js is portable. It is available on Microsoft Windows, macOS, Linux, Solaris, FreeBSD, OpenBSD, WebOS, and NonStop OS. Furthermore, it is well-supported by many web hosting providers, that often provide specific infrastructure and documentation for hosting Node sites.
* It has a very active third party ecosystem and developer community, with lots of people who are willing to help.

You can use Node.js to create a simple web server using the Node HTTP package.

### Hello Node.js

The following example creates a web server that listens for any kind of HTTP request on the URL `http://127.0.0.1:8000/` — when a request is received, the script will respond with the string: "Hello World". If you have already installed node, you can follow these steps to try out the example:

1. Open Terminal (on Windows, open the command line utility)
2. Create the folder where you want to save the program, for example, `test-node` and then enter it by entering the following command into your terminal:

```bash
cd test-node
```

3. Using your favorite text editor, create a file called `hello.js` and paste the following code into it:

```js
// Load HTTP module
const http = require("http");

const hostname = "127.0.0.1";
const port = 8000;

// Create HTTP server
const server = http.createServer(function (req, res) {
  // Set the response HTTP header with HTTP status and Content type
  res.writeHead(200, { "Content-Type": "text/plain" });

  // Send the response body "Hello World"
  res.end("Hello World\n");
});

// Prints a log once the server starts listening
server.listen(port, hostname, function () {
  console.log(`Server running at http://${hostname}:${port}/`);
});
```

4. Save the file in the folder you created above.
5. Go back to the terminal and type the following command:

```bash
node hello.js
```

Finally, navigate to `http://localhost:8000` in your web browser; you should see the text "**Hello World**" in the upper left of an otherwise empty web page.

Web Frameworks
--------------

Other common web-development tasks are not directly supported by Node itself. If you want to add specific handling for different HTTP verbs (e.g. `GET`, `POST`, `DELETE`, etc.), separately handle requests at different URL paths ("routes"), serve static files, or use templates to dynamically create the response, Node won't be of much use on its own. You will either need to write the code yourself, or you can avoid reinventing the wheel and use a web framework!

Introducing Express
-------------------

Express is the most popular *Node* web framework, and is the underlying library for a number of other popular Node web frameworks. It provides mechanisms to:

* Write handlers for requests with different HTTP verbs at different URL paths (routes).
* Integrate with "view" rendering engines in order to generate responses by inserting data into templates.
* Set common web application settings like the port to use for connecting, and the location of templates that are used for rendering the response.
* Add additional request processing "middleware" at any point within the request handling pipeline.

While *Express* itself is fairly minimalist, developers have created compatible middleware packages to address almost any web development problem. There are libraries to work with cookies, sessions, user logins, URL parameters, `POST` data, security headers, and *many* more. You can find a list of middleware packages maintained by the Express team at Express Middleware (along with a list of some popular 3rd party packages).

**Note:** This flexibility is a double edged sword. There are middleware packages to address almost any problem or requirement, but working out the right packages to use can sometimes be a challenge. There is also no "right way" to structure an application, and many examples you might find on the Internet are not optimal, or only show a small part of what you need to do in order to develop a web application.

Where did Node and Express come from?
-------------------------------------

Node was initially released, for Linux only, in 2009. The npm package manager was released in 2010, and native Windows support was added in 2012. Delve into Wikipedia if you want to know more.

Express was initially released in November 2010 and is currently on major version 4 of the API. You can check out the changelog for information about changes in the current release, and GitHub for more detailed historical release notes.

How popular are Node and Express?
---------------------------------

The popularity of a web framework is important because it is an indicator of whether it will continue to be maintained, and what resources are likely to be available in terms of documentation, add-on libraries, and technical support.

There isn't any readily-available and definitive measure of the popularity of server-side frameworks (although you can estimate popularity using mechanisms like counting the number of GitHub projects and StackOverflow questions for each platform). A better question is whether Node and Express are "popular enough" to avoid the problems of unpopular platforms. Are they continuing to evolve? Can you get help if you need it? Is there an opportunity for you to get paid work if you learn Express?

Based on the number of high profile companies that use Express, the number of people contributing to the codebase, and the number of people providing both free and paid for support, then yes, *Express* is a popular framework!

Is Express opinionated?
-----------------------

Web frameworks often refer to themselves as "opinionated" or "unopinionated".

Opinionated frameworks are those with opinions about the "right way" to handle any particular task. They often support rapid development *in a particular domain* (solving problems of a particular type) because the right way to do anything is usually well-understood and well-documented. However they can be less flexible at solving problems outside their main domain, and tend to offer fewer choices for what components and approaches they can use.

Unopinionated frameworks, by contrast, have far fewer restrictions on the best way to glue components together to achieve a goal, or even what components should be used. They make it easier for developers to use the most suitable tools to complete a particular task, albeit at the cost that you need to find those components yourself.

Express is unopinionated. You can insert almost any compatible middleware you like into the request handling chain, in almost any order you like. You can structure the app in one file or multiple files, and using any directory structure. You may sometimes feel that you have too many choices!

What does Express code look like?
---------------------------------

In a traditional data-driven website, a web application waits for HTTP requests from the web browser (or other client). When a request is received the application works out what action is needed based on the URL pattern and possibly associated information contained in `POST` data or `GET` data. Depending on what is required it may then read or write information from a database or perform other tasks required to satisfy the request. The application will then return a response to the web browser, often dynamically creating an HTML page for the browser to display by inserting the retrieved data into placeholders in an HTML template.

Express provides methods to specify what function is called for a particular HTTP verb (`GET`, `POST`, `PUT`, etc.) and URL pattern ("Route"), and methods to specify what template ("view") engine is used, where template files are located, and what template to use to render a response. You can use Express middleware to add support for cookies, sessions, and users, getting `POST`/`GET` parameters, etc. You can use any database mechanism supported by Node (Express does not define any database-related behavior).

The following sections explain some of the common things you'll see when working with *Express* and *Node* code.

### Helloworld Express

First lets consider the standard Express Hello World example (we discuss each part of this below, and in the following sections).

**Note:** If you have Node and Express already installed (or if you install them as shown in the next article), you can save this code in a text file called **app.js** and run it in a bash command prompt by calling:

**`node ./app.js`**

```js
const express = require("express");
const app = express();
const port = 3000;

app.get("/", function (req, res) {
  res.send("Hello World!");
});

app.listen(port, function () {
  console.log(`Example app listening on port ${port}!`);
});
```

The first two lines `require()` (import) the express module and create an Express application. This object, which is traditionally named `app`, has methods for routing HTTP requests, configuring middleware, rendering HTML views, registering a template engine, and modifying application settings that control how the application behaves (e.g. the environment mode, whether route definitions are case sensitive, etc.)

The middle part of the code (the three lines starting with `app.get`) shows a *route definition*. The `app.get()` method specifies a callback function that will be invoked whenever there is an HTTP `GET` request with a path (`'/'`) relative to the site root. The callback function takes a request and a response object as arguments, and calls `send()` on the response to return the string "Hello World!"

The final block starts up the server on a specified port ('3000') and prints a log comment to the console. With the server running, you could go to `localhost:3000` in your browser to see the example response returned.

### Importing and creating modules

A module is a JavaScript library/file that you can import into other code using Node's `require()` function. *Express* itself is a module, as are the middleware and database libraries that we use in our *Express* applications.

The code below shows how we import a module by name, using the *Express* framework as an example. First we invoke the `require()` function, specifying the name of the module as a string (`'express'`), and calling the returned object to create an Express application. We can then access the properties and functions of the application object.

```js
const express = require("express");
const app = express();
```

You can also create your own modules that can be imported in the same way.

**Note:** You will *want* to create your own modules, because this allows you to organize your code into manageable parts — a monolithic single-file application is hard to understand and maintain. Using modules also helps you manage your namespace, because only the variables you explicitly export are imported when you use a module.

To make objects available outside of a module you just need to expose them as additional properties on the `exports` object. For example, the **square.js** module below is a file that exports `area()` and `perimeter()` methods:

```js
exports.area = function (width) {
  return width \* width;
};
exports.perimeter = function (width) {
  return 4 \* width;
};
```

We can import this module using `require()`, and then call the exported method(s) as shown:

```js
const square = require("./square"); // Here we require() the name of the file without the (optional) .js file extension
console.log(`The area of a square with a width of 4 is ${square.area(4)}`);
```

**Note:** You can also specify an absolute path to the module (or a name, as we did initially).

If you want to export a complete object in one assignment instead of building it one property at a time, assign it to `module.exports` as shown below (you can also do this to make the root of the exports object a constructor or other function):

```js
module.exports = {
  area(width) {
    return width \* width;
  },

  perimeter(width) {
    return 4 \* width;
  },
};
```

**Note:** You can think of `exports` as a shortcut to `module.exports` within a given module. In fact, `exports` is just a variable that gets initialized to the value of `module.exports` before the module is evaluated. That value is a reference to an object (empty object in this case). This means that `exports` holds a reference to the same object referenced by `module.exports`. It also means that by assigning another value to `exports` it's no longer bound to `module.exports`.

For a lot more information about modules see Modules (Node API docs).

### Using asynchronous APIs

JavaScript code frequently uses asynchronous rather than synchronous APIs for operations that may take some time to complete. A synchronous API is one in which each operation must complete before the next operation can start. For example, the following log functions are synchronous, and will print the text to the console in order (First, Second).

```js
console.log("First");
console.log("Second");
```

By contrast, an asynchronous API is one in which the API will start an operation and immediately return (before the operation is complete). Once the operation finishes, the API will use some mechanism to perform additional operations. For example, the code below will print out "Second, First" because even though `setTimeout()` method is called first, and returns immediately, the operation doesn't complete for several seconds.

```js
setTimeout(function () {
  console.log("First");
}, 3000);
console.log("Second");
```

Using non-blocking asynchronous APIs is even more important on Node than in the browser because *Node* is a single-threaded event-driven execution environment. "Single threaded" means that all requests to the server are run on the same thread (rather than being spawned off into separate processes). This model is extremely efficient in terms of speed and server resources, but it does mean that if any of your functions call synchronous methods that take a long time to complete, they will block not just the current request, but every other request being handled by your web application.

There are a number of ways for an asynchronous API to notify your application that it has completed. The most common way is to register a callback function when you invoke the asynchronous API, that will be called back when the operation completes. This is the approach used above.

**Note:** Using callbacks can be quite "messy" if you have a sequence of dependent asynchronous operations that must be performed in order because this results in multiple levels of nested callbacks. This problem is commonly known as "callback hell". This problem can be reduced by good coding practices (see http://callbackhell.com/), using a module like async, or refactoring the code to native JavaScript features like Promises and async/await. Node offers the `utils.promisify` function to do the callback → Promise conversion ergonomically.

**Note:** A common convention for Node and Express is to use error-first callbacks. In this convention, the first value in your *callback functions* is an error value, while subsequent arguments contain success data. There is a good explanation of why this approach is useful in this blog: The Node.js Way - Understanding Error-First Callbacks (fredkschott.com).

### Creating route handlers

In our *Hello World* Express example (see above), we defined a (callback) route handler function for HTTP `GET` requests to the site root (`'/'`).

```js
app.get("/", function (req, res) {
  res.send("Hello World!");
});
```

The callback function takes a request and a response object as arguments. In this case, the method calls `send()` on the response to return the string "Hello World!" There are a number of other response methods for ending the request/response cycle, for example, you could call `res.json()` to send a JSON response or `res.sendFile()` to send a file.

**Note:** You can use any argument names you like in the callback functions; when the callback is invoked the first argument will always be the request and the second will always be the response. It makes sense to name them such that you can identify the object you're working with in the body of the callback.

The *Express application* object also provides methods to define route handlers for all the other HTTP verbs, which are mostly used in exactly the same way:

`checkout()`, `copy()`, **`delete()`**, **`get()`**, `head()`, `lock()`, `merge()`, `mkactivity()`, `mkcol()`, `move()`, `m-search()`, `notify()`, `options()`, `patch()`, **`post()`**, `purge()`, **`put()`**, `report()`, `search()`, `subscribe()`, `trace()`, `unlock()`, `unsubscribe()`.

There is a special routing method, `app.all()`, which will be called in response to any HTTP method. This is used for loading middleware functions at a particular path for all request methods. The following example (from the Express documentation) shows a handler that will be executed for requests to `/secret` irrespective of the HTTP verb used (provided it is supported by the http module).

```js
app.all("/secret", function (req, res, next) {
  console.log("Accessing the secret section…");
  next(); // pass control to the next handler
});
```

Routes allow you to match particular patterns of characters in a URL, and extract some values from the URL and pass them as parameters to the route handler (as attributes of the request object passed as a parameter).

Often it is useful to group route handlers for a particular part of a site together and access them using a common route-prefix (e.g. a site with a Wiki might have all wiki-related routes in one file and have them accessed with a route prefix of */wiki/*). In *Express* this is achieved by using the `express.Router` object. For example, we can create our wiki route in a module named **wiki.js**, and then export the `Router` object, as shown below:

```js
// wiki.js - Wiki route module

const express = require("express");
const router = express.Router();

// Home page route
router.get("/", function (req, res) {
  res.send("Wiki home page");
});

// About page route
router.get("/about", function (req, res) {
  res.send("About this wiki");
});

module.exports = router;
```

**Note:** Adding routes to the `Router` object is just like adding routes to the `app` object (as shown previously).

To use the router in our main app file we would then `require()` the route module (**wiki.js**), then call `use()` on the *Express* application to add the Router to the middleware handling path. The two routes will then be accessible from `/wiki/` and `/wiki/about/`.

```js
const wiki = require("./wiki.js");
// …
app.use("/wiki", wiki);
```

We'll show you a lot more about working with routes, and in particular about using the `Router`, later on in the linked section Routes and controllers.

### Using middleware

Middleware is used extensively in Express apps, for tasks from serving static files to error handling, to compressing HTTP responses. Whereas route functions end the HTTP request-response cycle by returning some response to the HTTP client, middleware functions *typically* perform some operation on the request or response and then call the next function in the "stack", which might be more middleware or a route handler. The order in which middleware is called is up to the app developer.

**Note:** The middleware can perform any operation, execute any code, make changes to the request and response object, and it can *also end the request-response cycle*. If it does not end the cycle then it must call `next()` to pass control to the next middleware function (or the request will be left hanging).

Most apps will use *third-party* middleware in order to simplify common web development tasks like working with cookies, sessions, user authentication, accessing request `POST` and JSON data, logging, etc. You can find a list of middleware packages maintained by the Express team (which also includes other popular 3rd party packages). Other Express packages are available on the npm package manager.

 To use third party middleware you first need to install it into your app using npm.
 For example, to install the morgan HTTP request logger middleware, you'd do this:

```bash
npm install morgan
```

You could then call `use()` on the *Express application object* to add the middleware to the stack:

```js
const express = require("express");
const logger = require("morgan");
const app = express();
app.use(logger("dev"));
// …
```

**Note:** Middleware and routing functions are called in the order that they are declared. For some middleware the order is important (for example if session middleware depends on cookie middleware, then the cookie handler must be added first). It is almost always the case that middleware is called before setting routes, or your route handlers will not have access to functionality added by your middleware.

You can write your own middleware functions, and you are likely to have to do so (if only to create error handling code). The **only** difference between a middleware function and a route handler callback is that middleware functions have a third argument `next`, which middleware functions are expected to call if they are not that which completes the request cycle (when the middleware function is called, this contains the *next* function that must be called).

You can add a middleware function to the processing chain for *all responses* with `app.use()`, or for a specific HTTP verb using the associated method: `app.get()`, `app.post()`, etc. Routes are specified in the same way for both cases, though the route is optional when calling `app.use()`.

The example below shows how you can add the middleware function using both approaches, and with/without a route.

```js
const express = require("express");
const app = express();

// An example middleware function
const a\_middleware\_function = function (req, res, next) {
  // Perform some operations
  next(); // Call next() so Express will call the next middleware function in the chain.
};

// Function added with use() for all routes and verbs
app.use(a_middleware_function);

// Function added with use() for a specific route
app.use("/someroute", a_middleware_function);

// A middleware function added for a specific HTTP verb and route
app.get("/", a_middleware_function);

app.listen(3000);
```

**Note:** Above we declare the middleware function separately and then set it as the callback. In our previous route handler function we declared the callback function when it was used. In JavaScript, either approach is valid.

The Express documentation has a lot more excellent documentation about using and writing Express middleware.

### Serving static files

You can use the express.static middleware to serve static files, including your images, CSS and JavaScript (`static()` is the only middleware function that is actually **part** of *Express*). For example, you would use the line below to serve images, CSS files, and JavaScript files from a directory named '**public'** at the same level as where you call node:

```js
app.use(express.static("public"));
```

Any files in the public directory are served by adding their filename (*relative* to the base "public" directory) to the base URL. So for example:
```

http://localhost:3000/images/dog.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/app.js
http://localhost:3000/about.html
```

You can call `static()` multiple times to serve multiple directories. If a file cannot be found by one middleware function then it will be passed on to the subsequent middleware (the order that middleware is called is based on your declaration order).

```js
app.use(express.static("public"));
app.use(express.static("media"));
```

You can also create a virtual prefix for your static URLs, rather than having the files added to the base URL. For example, here we specify a mount path so that the files are loaded with the prefix "/media":

```js
app.use("/media", express.static("public"));
```

Now, you can load the files that are in the `public` directory from the `/media` path prefix.
```

http://localhost:3000/media/images/dog.jpg
http://localhost:3000/media/video/cat.mp4
http://localhost:3000/media/cry.mp3
```

**Note:** See also Serving static files in Express.

### Handling errors

Errors are handled by one or more special middleware functions that have four arguments, instead of the usual three: `(err, req, res, next)`. For example:

```js
app.use(function (err, req, res, next) {
  console.error(err.stack);
  res.status(500).send("Something broke!");
});
```

These can return any content required, but must be called after all other `app.use()` and routes calls so that they are the last middleware in the request handling process!

Express comes with a built-in error handler, which takes care of any remaining errors that might be encountered in the app. This default error-handling middleware function is added at the end of the middleware function stack. If you pass an error to `next()` and you do not handle it in an error handler, it will be handled by the built-in error handler; the error will be written to the client with the stack trace.

**Note:** The stack trace is not included in the production environment. To run it in production mode you need to set the environment variable `NODE_ENV` to '`production'`.

**Note:** HTTP404 and other "error" status codes are not treated as errors. If you want to handle these, you can add a middleware function to do so. For more information see the FAQ.

For more information see Error handling (Express docs).

### Using databases

*Express* apps can use any database mechanism supported by *Node* (*Express* itself doesn't define any specific additional behavior/requirements for database management). There are many options, including PostgreSQL, MySQL, Redis, SQLite, MongoDB, etc.

In order to use these you have to first install the database driver using npm. For example, to install the driver for the popular NoSQL MongoDB you would use the command:

```bash
npm install mongodb
```

The database itself can be installed locally or on a cloud server. In your Express code you require the driver, connect to the database, and then perform create, read, update, and delete (CRUD) operations. The example below (from the Express documentation) shows how you can find "mammal" records using MongoDB.

This works with older versions of MongoDB version ~ 2.2.33:

```js
const MongoClient = require("mongodb").MongoClient;

MongoClient.connect("mongodb://localhost:27017/animals", (err, db) => {
  if (err) throw err;

  db.collection("mammals")
    .find()
    .toArray((err, result) => {
      if (err) throw err;

      console.log(result);
    });
});
```

For MongoDB version 3.0 and up:

```js
const MongoClient = require("mongodb").MongoClient;

MongoClient.connect("mongodb://localhost:27017/animals", (err, client) => {
  if (err) throw err;

  const db = client.db("animals");
  db.collection("mammals")
    .find()
    .toArray((err, result) => {
      if (err) throw err;
      console.log(result);
      client.close();
    });
});
```

Another popular approach is to access your database indirectly, via an Object Relational Mapper ("ORM"). In this approach you define your data as "objects" or "models" and the ORM maps these through to the underlying database format. This approach has the benefit that as a developer you can continue to think in terms of JavaScript objects rather than database semantics, and that there is an obvious place to perform validation and checking of incoming data. We'll talk more about databases in a later article.

For more information see Database integration (Express docs).

### Rendering data (views)

Template engines (also referred to as "view engines" by *Express*'s documentation) allow you to specify the *structure* of an output document in a template, using placeholders for data that will be filled in when a page is generated. Templates are often used to create HTML, but can also create other types of documents. Express has support for a number of template engines, and there is a useful comparison of the more popular engines here: Comparing JavaScript Templating Engines: Jade, Mustache, Dust and More.

In your application settings code you set the template engine to use and the location where Express should look for templates using the 'views' and 'view engine' settings, as shown below (you will also have to install the package containing your template library too!)

```js
const express = require("express");
const path = require("path");
const app = express();

// Set directory to contain the templates ('views')
app.set("views", path.join(__dirname, "views"));

// Set view engine to use, in this case 'some\_template\_engine\_name'
app.set("view engine", "some\_template\_engine\_name");
```

The appearance of the template will depend on what engine you use. Assuming that you have a template file named "index.<template\_extension>" that contains placeholders for data variables named 'title' and "message", you would call `Response.render()` in a route handler function to create and send the HTML response:

```js
app.get("/", function (req, res) {
  res.render("index", { title: "About dogs", message: "Dogs rock!" });
});
```

For more information see Using template engines with Express (Express docs).

### File structure

Express makes no assumptions in terms of structure or what components you use. Routes, views, static files, and other application-specific logic can live in any number of files with any directory structure. While it is perfectly possible to have the whole *Express* application in one file, typically it makes sense to split your application into files based on function (e.g. account management, blogs, discussion boards) and architectural problem domain (e.g. model, view or controller if you happen to be using an MVC architecture).

In a later topic we'll use the *Express Application Generator*, which creates a modular app skeleton that we can easily extend for creating web applications.

Summary
-------

Congratulations, you've completed the first step in your Express/Node journey! You should now understand Express and Node's main benefits, and roughly what the main parts of an Express app might look like (routes, middleware, error handling, and template code). You should also understand that with Express being an unopinionated framework, the way you pull these parts together and the libraries that you use are largely up to you!

Of course Express is deliberately a very lightweight web application framework, so much of its benefit and potential comes from third party libraries and features. We'll look at those in more detail in the following articles. In our next article we're going to look at setting up a Node development environment, so that you can start seeing some Express code in action.

See also
--------

* Venkat.R - Manage Multiple Node versions
* Modules (Node API docs)
* Express (home page)
* Basic routing (Express docs)
* Routing guide (Express docs)
* Using template engines with Express (Express docs)
* Using middleware (Express docs)
* Writing middleware for use in Express apps (Express docs)
* Database integration (Express docs)
* Serving static files in Express (Express docs)
* Error handling (Express docs)
* Overview: Express Nodejs
* Next