👉Taking A Dive Into Express' Request and Response Objects👈
Tags: express, webdev, backend, javascript
Published: 2023-08-05 06:25:49



HTTP requests and responses are a critical part of the modern communication standard of the internet. While backend frameworks such as Express abstract away much of the technical details of these, they often provide many properties and methods that allow developers to interact with them in interesting ways. Let's take a deep dive into what some of these are. 

## The Request Object

### 1. `req.params`

The `req.params` attribute is used to access parameters captured from the URL in a route. These parameters are typically defined in the route path as placeholders and are useful for creating dynamic routes. For example, if you have a route defined as `/users/:id`, you can access the `id` parameter using `req.params.id` in your route handler.

```js
const express = require('express')
const app = express()

app.get('/users/:id', (req, res) => {
  const userId = req.params.id
  // Use the userId in your route logic
})
// Example URL: /users/123
// req.params = {id: "123"}
...
```

### 2. `req.query`

The `req.query` attribute provides access to the query parameters sent in the URL. These parameters are usually appended to the URL after a question mark (`?`) and are useful for passing optional data to the server.

```js
...
app.get('/search', (req, res) => {
  const query = req.query.q
  // Use the query in your route logic
})
// Example URL: /search?breakfast=pie&dinner=cake
// req.query = {breakfast: "pie", dinner: "cake"}
...
```

### 3. `req.body`

To handle incoming data from HTML forms or JSON payloads, Express.js uses the `req.body` attribute. By default, `req.body` will be undefined unless you configure a body parser, such as express.json() or express.urlencoded().
Let's expore an example where we parse and handle incoming form data on a complaint submission form on our website:

```js
...
// For parsing application/json
app.use(express.json())

// For parsing application/x-www-form-urlencoded
app.use(express.urlencoded({ extended: true }))

// Present the user with the form
app.get('/submitComplaint', (req, res) => {
  res.render('complaintForm')
})

// Handle post requests from the form
app.post('/submitComplaint', (req, res) => {

  // Destructure properties from the req.body object
  const { 
    email, 
    phoneNumber,
    homeAddress, 
    complaint
} = req.body

// Record the user's IP address for future plans
const ip = req.ip 

// Legitimate business logic goes here. . .
})
...
```

### 4. `req.headers`

The `req.headers` attribute provides access to the HTTP headers sent by the client. For example, you can access information about the user's browser by accessing the user-agent information (`req.headers['user-agent']`), so that you can ~~target~~ warn or turn away users that are using outdated and vulnerable browser versions.

```js
...
app.get('/user-agent', (req, res) => {
  const userAgent = req.headers['user-agent'];
  // Use the userAgent in your route logic
})
...
```

## The Response Object

### 1. `res.send()`
`res.send()` is used to send a response to the client. The method takes a body parameter, and more commonly accepts a string, object, or an array.

```js
...
app.get('/:dataType', (req, res) => {
  let {dataType} = req.params
  dataType = dataType.toLowerCase()
  if (dataType == "string") {
    res.send('<p>Some HTML...</p>')

  // An array or object is represented as JSON.
  } else if (dataType == "object") {
      res.send({Hello: "World"})

  } else if (dataType == "array") {
      res.send([1, 2, 3])
  
  } else {
    // Error handling . . .
  } 
})
...
```
The body parameter can also accept a Buffer object or a Boolean value.

### 2. `res.status()`
`res.status` can be used to set the status code of the response. Check out [this guide](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) to see a list of common status codes.
You can chain `res.send()` on a call to `res.status()` to set the status of the response sent. 

In the previous example, we can send a `404 not found` status code to indicate the resource was not found on the server.

```js
...
  } else {
      res.status(404).send(<p>Resource not found.</p>)
  } 
```

### 3. `res.json()`

The `res.json()` method can also be used to send JSON to the client. This has the same functionality as sending an array or object (or array of objects) using `res.send()`.

```js
...
app.get('/:sendType', (req, res) => {
  let {sendType} = req.params
  sendType = sendType.toLowerCase()
  if (sendType == 'json') {
    res.json([{Hello: "World"}])  
  } 
  else if (sendType == 'send') {
    res.send([{Hello: "World"}])
  }
  // Both of these responses function the same
})
```
Personally, I would use `res.json()` if I wanted to send JSON and `req.send()` if I wanted to send a string to make the code easier to understand.

### 4. `res.redirect()`

The `res.redirect()` method is used to redirect the client to a different URL. By default, this will also set the status code to `302 Found` by default, but the method does take an optional parameter to set a custom status code.

```js
...
app.get('/:someUrl', (req, res) => {
  let {someUrl} = req.params
  someUrl = someUrl.toLowerCase()
  if (someUrl == 'default') {
    // Redirect the client to /thisUrl 
    // with status code `302 Found`.
    res.redirect('/thisUrl')
  }
  else if (someUrl == 'customStatus') {
    // Redirect the client to /anotherUrl
    // with the status code `301 Moved Permanently`.
    res.redirect(301, '/anotherUrl')
}
})
```
There you have it - some important attributes and methods of Express' request and response objects that you can use to help ~~hack and destroy~~ build up the future community and its tech stacks.

You can send questions to me only on the last Monday in February. But only on a leap day.

See you in 2044. 
##👋