Categories
Express JavaScript

Guide to the Express Request Object — Queries and Cookies

The request object lets us get the information about requests made from the client in middlewares and route handlers.

In this article, we’ll look at the properties of Express’s request object in detail, including query strings, URL parameters, and signed cookies.

Request Object

The req parameter we have in the route handlers above is the req object.

It has some properties that we can use to get data about the request that’s made from the client-side. The more important ones are listed below.

req.originalUrl

The originalUrl property has the original request URL.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();app.get('/', (req, res) => {  
  res.send(req.originalUrl);  
})app.listen(3000);

Then when we have the request with query string /?foo=bar , we get back /?foo=bar .

req.params

params property has the request parameters from the URL.

For example, if we have:

const express = require('express')  
const app = express()app.use(express.json())  
app.use(express.urlencoded({ extended: true }))app.get('/:name/:age', (req, res) => {  
  res.json(req.params)  
})app.listen(3000, () => console.log('server started'));

Then when we pass in /john/1 as the parameter part of the URL, then we get:

{  
    "name": "john",  
    "age": "1"  
}

as the response from the route above.

req.path

The path property has the path part of the request URL.

For instance, if we have:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();app.get('/:name/:age', (req, res) => {  
  res.send(req.path);  
})app.listen(3000);

and make a request to /foo/1 , then we get back the same thing in the response.

req.protocol

We can get the protocol string with the protocol property.

For example, if we have:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();app.get('/', (req, res) => {  
  res.send(req.protocol);  
})app.listen(3000);

Then when we make a request through HTTP we get backhttp .

req.query

The query property gets us the query string from the request URL parsed into an object.

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res) => {  
  res.json(req.query)  
})
app.listen(3000, () => console.log('server started'));

Then when we append ?name=john&age=1 to the end of the hostname, then we get back:

{  
    "name": "john",  
    "age": "1"  
}

from the response.

req.route

We get the current matched route with the route property.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();app.get('/', (req, res) => {  
  console.log(req.route);  
  res.json(req.route);  
})app.listen(3000);

Then we get something like the following from the console.log :

Route {  
  path: '/',  
  stack:  
   [ Layer {  
       handle: [Function],  
       name: '<anonymous>',  
       params: undefined,  
       path: undefined,  
       keys: [],  
       regexp: /^/?$/i,  
       method: 'get' } ],  
  methods: { get: true } }

req.secure

A boolean property that indicates if the request is made with via HTTPS.

For example, given that we have:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.get('/', (req, res) => {    
  res.json(req.secure);  
})
app.listen(3000);

Then we get false if the request is made via HTTP.

req.signedCookies

The signedCookies object has the cookie with the value deciphers from the hashed value.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const cookieParser = require('cookie-parser');  
const app = express();  
app.use(cookieParser('secret'));
app.get('/cookie', (req, res, next) => {  
  res.cookie('name', 'foo', { signed: true })  
  res.send();  
})
app.get('/', (req, res) => {  
  res.send(req.signedCookies.name);  
})
app.listen(3000);

In the code above, we have the /cookie route to send the cookie from our app to the client. Then we can get the value from the client and then make a request to the / route with the Cookie header with name as the key and the signed value from the /cookie route as the value.

For example, it would look something like:

name=s%3Afoo.dzukRpPHVT1u4g9h6l0nV6mk9KRNKEGuTpW1LkzWLbQ

Then we get back foo from the / route after the signed cookie is decoded.

req.stale

stale is the opposite of fresh . See req.fresh for more details.

req.subdomains

We can get an array of subdomains in the domain name of the request with the subdomains property.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.get('/', (req, res) => {  
  res.send(req.subdomains);  
})
app.listen(3000);

Then when we make a request to the / route, we get something like:

["beautifulanxiousflatassembler--five-nine"]

req.xhr

A boolean property that’s true is X-Requested-With request header field is XMLHttpRequest .

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.get('/', (req, res) => {  
  res.send(req.xhr);  
})
app.listen(3000);

Then when we make a request to the/ route with the X-Requested-With header set to XMLHttpRequest , we get back true .

Conclusion

There’re many properties in the request object to get many things.

We can get signed cookies with the Cookie Parser middleware. Query strings and URL parameters can access in various form with query , params , and route properties.

Also, we can get parts of the subdomain with the subdomains property.

Categories
Express JavaScript

Guide to the Express Request Object — Methods

The request object lets us get the information about requests made from the client in middlewares and route handlers.

In this article, we’ll look at the properties of Express’s request object methods in detail, including getting headers and query strings.

Methods

The request object has various methods.

req.accepts(types)

The accepts method checks the Accept request header for the value that’s sent with the header. It takes a string with the value of the data type that we want to check if it’s sent with the Accept request header.

It returns the best match, or if nothing matches, false is returned.

If false is returned, then the 406 response code should be returned since the data type isn’t accepted by our route.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.get('/', (req, res) => {  
  res.send(req.accepts('html'));  
})
app.listen(3000);

Then when we send the Accept header with a value that has html in it, then it’ll return html.

Otherwise, false will be returned.

Other examples include:

req.accepts('text/html')  
req.accepts(['json', 'text'])  
req.accepts('application/json')  
req.accepts('image/png')  
req.accepts('png')  
req.accepts(['html', 'json'])

req.acceptsCharsets(charset [, …]), req.acceptsEncodings(encoding [, …]), req.acceptsLanguages(lang [, …])

The method returns the first accepted charset of the specified character set. The charset is from the request’s Accept-Charset HTTP header field.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.get('/', (req, res) => {  
  res.send(req.acceptsCharsets('utf8'));  
})
app.listen(3000);

Then we get back the character set in the Accept-Charset HTTP header if it’s set.

acceptsEncodings returns the encoding based on the Accepts-Encoding HTTP header; and acceptsLanguages returns the encoding based on the Accepts-Language HTTP header.

req.get(field)

We can get the header field value with the get method. It takes the key of the header and it’s case-insensitive.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.get('/', (req, res) => {  
  res.send(req.get('content-type'));  
})
app.listen(3000);

Then when we make a request to the / route with the Content-Type header’s value set to text/cmd, then we get back text/cmd.

req.is(type)

The is method returns the Content-Type header’s value if it matches the type passed in. If the request has no body, the null is returned. Otherwise, false is returned.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.get('/', (req, res) => {  
  res.send(req.is('html'));  
})
app.listen(3000);

Then we get null since it’s a GET request, which has no request body.

On the other hand, if we have:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.post('/', (req, res) => {  
  res.send(req.is('html'));  
})
app.listen(3000);

When we make a POST request to the/ route with the Content-Type header set to text/html, then we get back html .

If the Content-Type header is set to something without html, then we get back false .

req.param(name [, defaultValue])

req.param gets the value from the query string’s search parameter with the given key.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.post('/', (req, res) => {  
  res.send(req.param('name', 'Joe'));  
})
app.listen(3000);

The code above get the search parameter value with the name key. The default value is set to 'Joe'.

Then when we make a request to /?name=jane, then we get jane. Otherwise, if the name search parameter isn’t specified, then we get Joe.

req.param is deprecated, so we should use req.params, req.body or req.query, as applicable instead.

Lookup is of query string, URL parameter and body values are performed in the following order:

  • req.params
  • req.body
  • req.query

req.range(size[, options])

The range method parses the Range header. The size parameter has the maximum size of the resource. The options parameter is an object which can have the following property:

  • combine — a boolean that specifies if overlapping and adjacent ranges should be combined.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();app.get('/', (req, res) => {  
  const range = req.range(20000);  
  if (range && range.type === 'bytes') {  
    res.json(range);  
  }  
  else {  
    res.send();  
  }  
})app.listen(3000);

Then when we make a GET request to / with the Range header set to bytes=200–1000, 2000–6576, 19000- , we get:

[  
    {  
        "start": 200,  
        "end": 1000  
    },  
    {  
        "start": 2000,  
        "end": 6576  
    },  
    {  
        "start": 19000,  
        "end": 19999  
    }  
]

since we specified the size parameter to be 20000, so the last end value is 19999.

If we didn’t specify bytes in the value, we get nothing.

Conclusion

The request object has methods to parse query strings and get various headers like the Range, Accepts and Content-Type headers.

We can get the Range header with range, Accepts with accepts and Content-Type with is.

The get method can get any request header field’s value.

Categories
GraphQL JavaScript Nodejs

An Introduction to GraphQL

GraphQL is a query language for our API and a server-side runtime for running queries by using a type system for our data.

In this article, we’ll look at how to make basic queries to a GraphQL API.

Defining the API

We define an API by defining the types and fields for those types and provide functions for each field on each type.

For example, if we have the following type:

type Query {  
  person: Person  
}

Then we have to create a function for the corresponding type to return the data:

function Query_person(request) {  
  return request.person;  
}

Making Queries

Once we have a GraphQL service running, we can send GraphQL queries to validate and execute on the server.

For example, we can make a query as follows:

{  
  person {  
    firstName  
  }  
}

Then we may get JSON like the following:

{  
  "person": {  
    "firstName": "Joe"  
  }  
}

Queries and Mutations

Queries are for getting data from the GraphQL server and mutations are used for manipulating data stored on the server.

For example, the following is a query to get a person’s name:

{  
  person {  
    name  
  }  
}

Then we may get the following JSON from the server:

{  
  "data": {  
    "person": {  
      "name": "Joe"  
    }  
  }  
}

The field name returns a String type.

We can change the query as we wish if we want to get more data. For example, if we write the following query:

{  
  person {  
    name  
    friends {  
      name  
    }  
  }  
}

Then we may get something like the following as a response:

{  
  "data": {  
    "person": {  
      "name": "Joe",  
      "friends": [  
        {  
          "name": "Jane"  
        },  
        {  
          "name": "John"  
        }  
      ]  
    }  
  }  
}

The example above has friends being an array. They look the same from the query perspectively, but the server knows what to return based on the type specified.

Arguments

We can pass in arguments to queries and mutations. We can do a lot more with queries if we pass in arguments to it.

For example, we can pass in an argument as follows:

{  
  person(id: "1000") {  
    name      
  }  
}

Then we get something like:

{  
  "data": {  
    "person": {  
      "name": "Luke"  
    }  
  }  
}

from the server.

With GraphQL, we can pass in arguments to nested objects. For example, we can write:

{  
  person(id: "1000") {  
    name  
    height(unit: METER)  
  }  
}

Then we may get the following response:

{  
  "data": {  
    "person": {  
      "name": "Luke",  
      "height": 1.9  
    }  
  }  
}

In the example, the height field has a unit which is an enum type that represents a finite set of values.

unit may either be METER or FOOT.

Fragments

We can define fragments to let us reuse complex queries.

For example, we can define a fragment and use it as follows:

{  
  leftComparison: person(episode: FOO) {  
    ...comparisonFields  
  }  
  rightComparison: person(episode: BAR) {  
    ...comparisonFields  
  }  
}  
​  
fragment comparisonFields on Character {  
  name  
  appearsIn  
  friends {  
    name  
  }  
}

In the code above, we defined the comparisonFields fragment which has the list of fields we want to include in each query.

Then we have the leftComparison and rightComparison queries which include the fields of the comparisonFields fragment by using the ... operator.

Then we get something like:

{  
  "data": {  
    "leftComparison": {  
      "name": "Luke",  
      "appearsIn": [  
        "FOO",  
        "BAR"  
      ],  
      "friends": [  
        {  
          "name": "Jane"  
        },  
        {  
          "name": "John"  
        }  
      ]  
    },  
    "rightComparison": {  
      "name": "Mary",  
      "appearsIn": [  
        "FOO",  
        "BAR"  
      ],  
      "friends": [  
        {  
          "name": "Mary"  
        },  
        {  
          "name": "Alex"  
        }  
      ]  
    }  
  }  
}

Using variables inside fragments

We can pass in variables into fragments as follows:

query PersonComparison($first: Int = 3){  
  leftComparison: person(episode: FOO) {  
    ...comparisonFields  
  }  
  rightComparison: person(episode: BAR) {  
    ...comparisonFields  
  }  
}  
​  
fragment comparisonFields on Character {  
  name  
  appearsIn  
  friends(first: $first) {  
    name  
  }  
}

Then we may get something like:

{  
  "data": {  
    "leftComparison": {  
      "name": "Luke",  
      "appearsIn": [  
        "FOO",  
        "BAR"  
      ],  
      "friends": [  
        {  
          "name": "Jane"  
        },  
        {  
          "name": "John"  
        }  
      ]  
    },  
    "rightComparison": {  
      "name": "Mary",  
      "appearsIn": [  
        "FOO",  
        "BAR"  
      ],  
      "friends": [  
        {  
          "name": "Mary"  
        },  
        {  
          "name": "Alex"  
        }  
      ]  
    }  
  }  
}

as a response.

The operation type may either be a query, mutation, or subscription and describes what operator we’re intending to do. It’s required unless we’re using the query shorthand syntax. In that case, we can’t supply a name or variable definition for our operation.

The operation name is a meaningful and explicit name for our operation. It’s required in multi-operation documents. But its use is encouraged because it’s helpful for debugging and server-side logging.

It’s easy to identify the operation with a name.

Conclusion

GraphQL is a query language that lets us send requests to a server in a clear way. It works by sending nested objects with operation type and name along with any variables to the server.

Then the server will return us the response that we’re looking for.

Operation types include queries for getting data and mutations for making changes to data on the server.

Categories
Express JavaScript Nodejs

Storing User Sessions on the Server with Express-Session

To store confidential session data, we can use the express-session package. It stores the session data on the server and gives the client a session ID to access the session data.

In this article, we’ll look at how to use it to store temporary user data.

Installation

express-session is a Node package. We can install it by running:

npm install express-session

Then we can include it in our app by adding:

const session = require('express-session');

Usage

The session function returns a middleware to let us store sessions. It takes an option object with the following properties:

cookie

Settings object for the session ID cookie. The default value is:

{ path: '/', httpOnly: true, secure: false, maxAge: null }.

It takes the following properties:

cookie.domain

It specifies the value for the Domain Set-Cookie attribute. No domain is set by default. Most clients will consider the cookie to apply only to the current domain.

cookie.expires

This specifies the Date object of the value for the Expires Set-Cookie attribute. No expiration date is set by default. This means the cookie will be deleted when the session ends.

If both expires and maxAge are set, then the last one defined if what’s used. expires shouldn’t be set directly. We should set maxAge .

cookie.httpOnly

Specifies the boolean value for the HttpOnly Set-Cookie attribute. When it’s truthy, the HttpOnly attribute is set. Otherwise, it’s not. By default, only HttpOnly attribute is set.

cookie.maxAge

The number of milliseconds to use when calculating the Expires Set-Cookie attribute. This is calculated by taking the current server time and adding maxAge milliseconds to it to calculate the Expires datetime. No maximum age is set by default.

cookie.path

Sets the Path Set-Cookie attribute value. This is set to / by default which is the root path of the domain.

cookie.sameSite

A boolean or string for the value of the SameSite Set-Cookie attribute. It can be:

  • true — will set the SameSite attribute to Strict for strict same site enforcement
  • false — won’t set the SameSite attribute
  • 'lax' — set the SameSite attribute to Lax for lax same-site enforcement
  • 'strict' set the SameSite attribute to Strict for strict same-site enforcement

cookie.secure

Boolean value for the Secure Set-Cookie attribute. The Secure attribute is set. Otherwise, it’s not.

Cookies won’t be sent over HTTP connects if this is set to true .

However, it’s recommended. If the app is hosted behind a proxy, then trust proxy must be set if secure is set to true .

genid

A function to generate a new session ID. The default value is a function that uses the uid-safe library to generate IDs.

name

The name of the session ID cookie to set in the response. The default value is 'connect.sid' .

proxy

Trust the reverse proxy when setting cookies via the X-Forwarded-Proto header.

The default value is undefined . Other possibles include:

  • true — the X-Forwarded-Proto header will be used
  • false — all headers are ignored and the connection is considered secure only if it’s a direct SSL/TLS connection
  • undefined — uses the 'trust proxy' setting from Express

resave

Forces the session to be saved back to the session store even if the session was never modified during the request.

This may create race conditions when a client makes 2 parallel requests to our server and changes made to the session on one request may be overwritten when the other request ends.

Defaults to true , but the default may change in the future. false makes more sense as the option.

rolling

Force a session identifier cookie to be set on every response. The expiration is reset to the original maxAge , resetting the expiration countdown.

Defaults to false .

When this is set to true and saveUnintialized option is false , the cookie won’t be set on a response with uninitialized session

saveUnitialized

Force a session that’s uninitialized to be saved to the store. A session is uninitialized when it’s new but not modified. Setting this to false reduces server storage usage and comply with laws that require permission before storing cookies.

secret

This is a required option for the secret to sign the session ID cookie. It can be a string or an array of multiple string secrets.

store

The session store instance. It defaults to a new MemoryStore instance.

unset

Controls the result of unsetting req.session through delete , setting to null , etc.

Defaults to 'keep' . The possible values are:

  • 'destroy' — the session will be deleted when the response ends
  • 'keep' — the session will be kept but modifications made during the request aren’t saved.

req.session

We access the session data by using req.session . The data is typically JSON, so nested objects are fine.

req.session comes with the following methods:

regenerate(callback)

We call this to regenerate the session. Once it’s called, a new session ID and Session instance will be initialized at req.session and the callback will be called.

destroy(callback)

Destroys a session. req.session will be unset. Once it’s called, the callback will be called.

reload(callback)

Reloads the session data from the store and re-populates the req.session object. Once it’s done, the callback will be called.

save(callback)

Saves a session back to the store, replacing the contents of the store with the contents in memory.

This usually doesn’t need to be called.

touch()

Updates the maxAge property. This shouldn’t be called usually as this is done automatically.

id

We can get the session ID with the id property.

cookie

This property has the cookie content. This also lets us alter the cookie for the user.

Cookie.maxAge

We can set the maxAge property to change the expiry time in milliseconds.

Cookie.originalMaxAge

We can use this to get the original maxAge value in milliseconds.

req.sessionID

We can get the session ID of the loaded session with sessionId .

Implementing our Own Session Store

Session store must implement EventEmitter with additional methods.

store.all(callback)

An optional method to get all sessions in the store as an array. The callback signature is callback(error, sessions) and it’s called once the session is retrieved.

store.destroy(sid, callback)

A required method to delete a session from the store given the session ID. The callback has the signaturecallback(error) . It’s called once the session is deleted.

store.clear(callback)

An optional method to delete all sessions from the store. The callback signature is callback(error) and it called once the store is cleared.

store.length(callback)

An optional method to count all the sessions in the store. The callback has the signature callback(error, len).

store.get(sid, callback)

A required method to get the session data by the session ID (sid ). The callback has the signature callback(error, session) .

The session is returned if found, otherwise returns null or undefined .

store.set(sid, session, callback)

A required method to set the session given the sid , which is the session ID. The callback has the signature callback(error) once the session is set.

store.touch(sid, session, callback)

This method is suggested to be implemented. This is used to signal to the store that the given session is active. The callback has the signature callback(error) .

Example

An example would be storing the number of views and keep that data for 365 days. We can do that as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const session = require('express-session');  
const app = express();  
app.set('trust proxy', 1)  
app.use(session({  
  secret: 'secret',  
  resave: true,  
  cookie: {  
    maxAge: 24 * 60 * 60 * 365 * 1000  
  }  
}))
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', (req, res) => {  
  if (req.session.views) {  
    req.session.views++;  
  }  
  else {  
    req.session.views = 1;  
  }  
  res.send(`${req.session.views} views`);  
})
app.listen(3000);

In the code, we have the secret so that the cookie will be signed. Then in our route handler, we can get and set the data by getting and setting req.session.views , which we created.

Then we should see the number of views as we keep reloading the / route. It sets to expire in 365 days by setting maxAge, so the number will keep going up.

In the response header, we should get that the Set-Cookie response header has a value like:

connect.sid=s%3Ad6jfPu5awWj3EXPF-MdtU8cPzjOY5NRT.33nyXjKdShPAPyw9WWwY4sywP44IOX5SPSt2WUkH0cs; Path=/; Expires=Mon, 28 Dec 2020 00:47:31 GMT; HttpOnly

We have the value of the session ID and expiry time.

Conclusion

We can use the express-session package to keep session cookie data on the server-side.

There’re many options like the content of various cookie attributes and the time to expiry.

Other settings like the ID, whether to save cookie only in HTTPS and so on can be set.

The cookies will be stored in a session store. We can also implement our own store if we aren’t satisfied with the existing stores that are available for us to use.

Categories
Express JavaScript

Guide to the Express Request Object — Body, Cookies and More

The request object lets us get the information about requests made from the client in middlewares and route handlers.

In this article, we’ll look at the properties of Express’s request object in detail, including getting the request body and cookies.

Request Object

The req parameter we have in the route handlers above is the req object.

It has some properties that we can use to get data about the request that’s made from the client-side. The more important ones are listed below.

req.app

The req.app property holds a reference to the instance of an Express app that’s using the middleware.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const path = require('path');  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.set('foo', 'bar');
app.get('/', (req, res) => {  
  res.send(req.app.get('foo'));  
})
app.listen(3000);

We ran app.set(‘foo’, ‘bar’); to set the foo setting to the value'bar' , and then we can get the value with req.app ‘s get method.

req.baseUrl

The req.baseUrl property holds the base URL of the router instance that’s mounted.

For example, if we have:

const express = require('express');
const app = express();  
const greet = express.Router();  
greet.get('/', (req, res) => {  
  console.log(req.baseUrl);  
  res.send('Hello World');  
})
app.use('/greet', greet);
app.listen(3000, () => console.log('server started'));

Then we get /greet from the console.log .

req.body

req.body has the request body. We can parse JSON bodies with express.json() and URL encoded requests with express.urlencoded() .

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.post('/', (req, res) => {  
  res.json(req.body)  
})
app.listen(3000, () => console.log('server started'));

Then when we make a POST request with a JSON body, then we get back the same that we sent in the request.

req.cookies

We can get cookies that are sent by the request with the req.cookies property.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const cookieParser = require('cookie-parser');  
const app = express();  
app.use(cookieParser());
app.get('/', (req, res) => {  
  res.send(req.cookies.name);  
})
app.listen(3000);

Then when we send the Cookie request header with name as the key like name=foo , then we get foo displayed.

req.fresh

The fresh property indicates that the app is ‘fresh’. App app is ‘fresh’ if the cache-control request-header doesn’t have a no-cache directive and any of the following are true :

  • if-modified-since request header is specified and last-modified request header is equal to or earlier than the modified request header.
  • if-none-match request header is *
  • if-none-match request header, after being parsed into its directives, doesn’t match the etag response header.

We can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const path = require('path');  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', (req, res) => {  
  res.send(req.fresh);  
})
app.listen(3000);

Then we should get false if those conditions aren’t met.

req.hostname

We can get the hostname from the HTTP header with req.hostname .

When the trust proxy setting doesn’t evaluate to false , then Express will get the value from the X-Forwarded-Host header field. The header can be set by the client or by the proxy.

If there’s more than one X-Forwarded-Host header, then the first one will be used.

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res) => {  
  res.json(req.hostname)  
})
app.listen(3000, () => console.log('server started'));

Then we get the domain name that the app is hosted in if there’re no X-Forwarded-Host headers and trust proxy doesn’t evaluate to false .

req.ip

We can get the IP address that the request is made from with this property.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const cookieParser = require('cookie-parser');  
const app = express();  
app.use(cookieParser());
app.get('/', (req, res) => {  
  res.send(req.ip);  
})
app.listen(3000);

Then we get something like ::ffff:172.18.0.1 displayed.

req.ips

When the trust proxy setting isn’t false , this property contains the array of IP address specified by the X-Forwarded-For request header.

Otherwise, it’s an empty array. The X-Forwarded-For can be set by the client or the proxy.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();  
app.set('trust proxy', true);
app.get('/', (req, res) => {  
  res.send(req.ips);  
})
app.listen(3000);

Then we get the remote IPs from the client or the X-Forwarded-For header.

req.method

The method property has the request method of the request, like GET, POST, PUT or DELETE.

Conclusion

The request object has many properties for getting various pieces of information about the HTTP request received.

Third-party middleware like cookie-parser adds new properties to the request object to get things like cookies data and more.