How to create Custom Headers with Express and TypeScript
Recently, I had to create a cloud function that will store some data in a PostgreSQL database. Once I had done everything, or at least I had finished with the minimal functionality, I had to add some kind of basic authentication for my endpoint. Nothing new, we just use a custom standard header here, “enterprise-key”, that will tell me which client is performing the request.
Pretty easy, you may think, but it took me almost 5 hours of research to figure out how to achieve it. Since I want to help anyone who may have the same problem, I decided to write this article. Let’s do this!
I will assume you know a little bit about Node.js, Express, TypeScript, and so on. The first thing you need to do is to create a CustomRequest interface that will extend from the Request interface of Express, something like this:
import { Request } from 'express'
interface CustomRequest extends Request {}
export { CustomRequest }
So far, so good. At this point, we are able to add as many attributes as we want, but they have to be optional (using the ? operator), for example:
By doing this, you will be able to access myAwesomeProperty
as an attribute of the request
object. Now you may think that the next step is to create a property called headers and define it as an object and add there our new property, customHeader
for instance:
import { Request } from 'express'
interface CustomRequest extends Request {
enterpriseID?: number
headers : {
customHeader?: string
}
}
export { CustomRequest }
If you use the code above and try to access the customHeader
attribute from the headers
, you will have a huge error from your compiler, something like:
No overload matches this call. (...)
Types of property 'headers' are incompatible.
Property 'customHeader' is missing in type 'IncomingHttpHeaders' but required in type '{ customHeader: string; }'.ts(2769)
And here we are, the point where everything started. As usual, a pretty complex and unintelligible error, but we can solve it. You may notice that the important things here are the IncomingHttpHeaders
type and our customHeader
property. If you check the definition of Request you will notice that it extends from core.Request
interface which, in turn, extends from the http.IncomingMessage
class, and this class has a property called headers
guess what, its type is IncomingHttpHeaders(which comes from http
module). We found it!
So now we know that the headers
are from a certain type, but we can’t extend a type in TypeScript, right? Well, it may be true in the strict sense of the word, but there is a way to “extend” types in TypeScript (please check this for more information). The way to do this is by using intersection, when we intersect two or more types, we create a new type from them by using the & operator. So our next step will be importing IncomingHttpHeaders
from http
and intersecting it with our custom header(s).
import { IncomingHttpHeaders } from 'http'
import { Request } from 'express'
interface CustomRequest extends Request {
myAwesomeProperty?: number
headers : IncomingHttpHeaders & {
customHeader?: string
}
}
export { CustomRequest }
Are we done? Not really. If you leave the article here, you will probably face the same error I had — whenever I tried to access my customHeader
, I got undefined, for no apparent reason at all. Without any explanation, you may not be able to access your new custom header. But there is a solution! Just change the customHeader
attribute to snake case it would be: custom-header
or Custom-Header
and there you go, now by using brackets (req.headers['custom-header']
) you will be able to access your own headers.
Why do we have to do this? Why does Express doesn’t seem to be able to access our custom header when it is using camel case? I have no idea, but if you do, feel free to comment here why and we can all benefit from your answer.