How to integrate http2 with ExpressJS using nodejs module http2?

Diesan Romero picture Diesan Romero · Dec 30, 2019 · Viewed 7.5k times · Source

I am creating an api with nodejs and express and I want to integrate http2 with ExpressJS

This is my code:

'use strict';

const http2 = require('http2');
const fs = require('fs');
const path = require('path');

const express = require('express');
const bodyParser = require('body-parser');

const app = express();
const port = process.env.PORT || 443;

// Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

// Routes variables
const indexRouter = require('./routes/index');

// Routes uses
app.use('/', indexRouter);

// Server configurations
const key = path.join(__dirname + '/security/key.pem');
const cert = path.join(__dirname + '/security/certificate.pem');

const options = {
    key: fs.readFileSync(key),
    cert: fs.readFileSync(cert)
}

const server = http2.createSecureServer(options, app);

server.on('error', err => console.log(err));

server.listen(port, err => {
    if (err) throw err;
})

I am trying to pass express server as second parameter of createSecureServer() but I am not sure if I am right with this, cause I am getting this error:

[nodemon] 2.0.2 [nodemon] to restart at any time, enter rs [nodemon] watching dir(s): . [nodemon] watching extensions: js,mjs,json [nodemon] starting node index.js _http_incoming.js:96 if (this.socket.readable) ^

TypeError: Cannot read property 'readable' of undefined at IncomingMessage._read (_http_incoming.js:96:19) at IncomingMessage.Readable.read (_stream_readable.js:491:10) at resume_ (_stream_readable.js:976:12) at processTicksAndRejections (internal/process/task_queues.js:80:21) [nodemon] app crashed - waiting for file changes before starting...

It should be noted that my certificate, although self-signed and unreliable, is loading correctly. I try not to use a third-party module if I can do it with NodeJS. Any help?

Answer

Sandeep Patel picture Sandeep Patel · Jan 2, 2020

expressjs still does not officially support Node http2

enter image description here

For more details visit here

But you can use node-spdy. With this module, you can create HTTP2 / SPDY servers in node.js with natural http module interface and fallback to regular https (for browsers that support neither HTTP2 nor SPDY yet).

 const port = 3000
    const spdy = require('spdy')
    const express = require('express')
    const path = require('path')
    const fs = require('fs')
    
    const app = express()
    
    app.get('*', (req, res) => {
        res
          .status(200)
          .json({message: 'ok'})
    })
    const options = {
        key: fs.readFileSync(__dirname + '/server.key'),
        cert:  fs.readFileSync(__dirname + '/server.crt')
    }
    console.log(options)
    spdy
      .createServer(options, app)
      .listen(port, (error) => {
        if (error) {
          console.error(error)
          return process.exit(1)
        } else {
          console.log('Listening on port: ' + port + '.')
        }
      })

For more datils on spdy, visit here.

if you have an option for other frameworks you can use 'KOA' or 'HAPI' which have support for node http2. This might be useful for you

Also, Read this Release 5.0#2237, It says that:

The goal of Express 5 is to be API tweaks & the removal of all code from the Express repository, moving into components in the pillarjs project (https://github.com/pillarjs), providing at least basic support for promise-returning handlers and complete HTTP/2 functionality. Express 5 would become a "view into pillarjs" and would be an arrangement of these components.