Adonisjs and HTTP/2 Server Push?

Is there any good example or best practice on how to implement HTTP/2 server push with AdonisJs framework? I am using Nginx as proxy server.

Thanks

2 Likes

In your NGINX location block, add the preload directive as on the last line: http2_push_preload on

server {

  ## Ensure that HTTP/2 is enabled for the server        
  listen 443 ssl http2;

  ## Configure your SSL certificates
  ssl_certificate ssl/certificate.pem;
  ssl_certificate_key ssl/key.pem;

  server_name myapp.com;

  location / {
    proxy_pass http://localhost:3333;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_cache_bypass $http_upgrade;

    ## Activate Link header interception
    ## Since you won't be able to add each resource 
    ## to be pushed in this configuration
    http2_push_preload on;
  }
}

In your Adonis controller or route, programmatically add the resources to be preloaded via the Link header of your response. NGINX will intercept the response on it way out and make additional requests to the resources assigned in the Link header.

class UserController {
  async index({ request, response }) {

    const User = use('App/Models/User')
    const users = await User.all()

    // Add header. The path in the Link header must be absolute – relative paths 
    // like ./style.css are not supported. The path can optionally 
    // include a query string.
    // Also note that the angle brackets, < and >, and important when specifying
    // the path of the resource.
    // The structure of the path is <${absolute_path}>
    //
    // For CSS styles  
    response.header('Link', '</css/style.css>; as=style; rel=preload')

    // or for images
    response.header('Link', '</logos/thumbnails/logo.png>; as=image; rel=preload')

    // or for preloading an API endpoint
    response.header('Link', '</profile>; as=fetch; rel=preload')

    // You can add more than one resource by separating with commas
    response.header('Link', '</profile?user_id=123>; as=fetch; rel=preload', '</user/permissions?user_id=123>; as=fetch; rel=preload')

    // return your response as usual:
    return response.status(200).json({
        message: 'Query successful.',
        data: users,
        status: 200,
        statusText: 'OK',
      });
  }

For more as attributes see: https://w3c.github.io/preload/#as-attribute
For more on HTTP/2 Server push, see here: https://www.nginx.com/blog/nginx-1-13-9-http2-server-push/

Let me know if this works. Cheers!