Exposing NestJS Modules' GraphQL Endpoints with Reverse Proxy

When it comes to exposing GraphQL endpoints for each module while maintaining isolation, challenges arise. The necessity to expose these endpoints through a single port with different paths adds another layer of complexity. Enter reverse proxy configuration at the application level, a solution that can addresses these challenges.

Understanding Reverse Proxy Configuration

The provided code snippet offers a robust solution for exposing NestJS modules' GraphQL endpoints through a single port with distinct paths. Let's delve into how it achieves this feat:

import { createProxyMiddleware } from 'http-proxy-middleware';

export async function bootstrapNestApp(options: Options) {
 
// Configuration and initialization...

 for (const module of options.modules) {
   const moduleConfig = getModuleMapping(config, module.name);
   if (!moduleConfig) {
     throw new Error(`Module ${module.name} not found in config`);
   }

   
// Create a reverse proxy for each module
   globalApp.use(
     `/${moduleConfig.path || ''}`,
     createProxyMiddleware({
       target: `${BASE_URL}:${moduleConfig.port}`,
       changeOrigin: true,
       ws: true,
       onProxyReq: (proxyReq, req, res) => {
         logger.log(`Proxy request ${req.url} to ${BASE_URL}:${moduleConfig.port}`);
       },
       onError: (err, req, res) => {
         logger.error(err);
       },
     }),
   );
 }

 
// Other application startup and logging...

}

Reverse Proxy Setup

The heart of the solution lies in the configuration of reverse proxies for each module. This setup allows incoming requests to be forwarded to the appropriate module based on the requested path. Here's how it works:

  • The createProxyMiddleware function from the http-proxy-middleware package is utilized to set up the reverse proxy.
  • For each module specified in the options.modules array, a reverse proxy is created.
  • The reverse proxy forwards requests to the designated module's port.
  • The changeOrigin option ensures that the origin of the request is preserved during forwarding.
  • WebSocket support is enabled by setting the ws option to true.
  • Error handling and logging mechanisms are integrated to ensure robustness and visibility into proxy operations.

Path Configuration

The reverse proxy configuration takes into account the path configurations specified for each module. By using the moduleConfig.path property, requests are appropriately routed to the corresponding module.

Conclusion

The reverse proxy configuration presented in the code snippet offers a nice to have solution for exposing NestJS modules' GraphQL endpoints through a single port with distinct paths.