> For the complete documentation index, see [llms.txt](https://ga0-2.gitbook.io/seifxr10anz-content/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ga0-2.gitbook.io/seifxr10anz-content/week-14/day-1-promises-and-intro-to-express/intro-to-express.md).

# Intro to Express

#### Create a New Express Project

```bash
mkdir starlight
cd starlight
touch app.js
npm init -y
npm i express
```

#### Set Up a Basic Express Server

In `app.js`:

```javascript
const express = require('express')

const app = express()
const port = 3000

app.listen(port, () => {
  console.log(`Server listening on port ${port}`)
})
```

Then start the server with:

```bash
node app.js
```

This starts a server on port 3000 and… does nothing.

#### GET Routes

To respond to GET requests, use the `app.get` method:

```javascript
app.get('/', () => {
  console.log('Index route / hit')
})
```

Web servers are long-running processes. If you make any changes to the code, you'll need to stop the server with `Control-c` and then start it again with `node app.js`.

Once you're restarted the server, visit `localhost:3000` in your web browser, you should see the text `"Index route / hit"` in your terminal but nothing in your web browser.

To send a response back to the browser, you can use `res.send`:

```javascript
app.get('/', (req, res) => {
  console.log('Index route / hit')
  res.send('Hello world')
})
```

Or return some HTML:

```javascript
app.get('/', (req, res) => {
  console.log('Index route / hit')
  res.send('<h1>Hello world</h1>')
})
```

Restart the server and reload `localhost:3000`. You should now see the text `Hello world` in the web browser.

**NOTE** You can only send one response for every request. If you try to send multiple responses you'll get an error.

#### `req` & `res`

* `req` is an object containing information about the HTTP request (HTTP method, request body, ip address, query params, etc).
* `res` is an object representing the HTTP response, which is used to send something back to the client.

#### POST Routes

To handle form submissions, you have to tell Express to parse the incoming form data using the `urlencoded` middleware. In the POST route, the form data is available in `req.body`.

```javascript
app.use(express.urlencoded({ extended: true }))

app.post('/', (req, res) => {
  res.send(req.body)
})
```

#### Route Parameters

To capture the value of the dynamic path segment of the URL, define a GET route with a route parameter (note the `:` in `:bookID`). The value of the route parameter can be accessed in the `req.params` object.

```javascript
app.get('/books/:bookID', (req, res) => {
  console.log(req.params.bookID)
})
```

You can define as many route params as you want as long as they're named differently:

```javascript
app.get('/hello/:firstname/:lastname', (req, res) => {
  console.log(req.params)
  res.send(`Hello ${req.params.firstname} ${req.params.lastname}!`)
})
```

In your browser, go to `localhost:3000/hello/taylor/hebert`.

#### Query Parameters

To get the values in a query string, use `req.query`.

```javascript
// localhost:3000/books?page=2&limit=12
app.get('/books', (req, res) => {
  console.log(req.query)
})
```

#### nodemon

Restarting the server manually any time you want to test changes to the code is tedious. Using an npm package called `nodemon`, you can automate this process and streamline your workflow.

```bash
npm i -g nodemon
```

The `-g/--global` flag installs an npm package so that any project can use it. **NOTE** If you're using `nvm`, globally installed packages will only be available for the version of node you were using when you installed the package.

Start your server with:

```bash
nodemon
```

Nodemon will look for the `"main"` property in your package.json and execute that .js file. If you have `"app.js"` as `"main"` in package.json then the above command is equivalent to:

```bash
nodemon app.js
```

Nodemon will watch for any changes you to make to your code and restart the server automatically.
