pulumi-cloud icon indicating copy to clipboard operation
pulumi-cloud copied to clipboard

Allow Promise Based cloud.HttpServer

Open WonderPanda opened this issue 7 years ago • 4 comments

Hey @CyrusNajmabadi I wanted to continue our discussion from https://github.com/pulumi/pulumi/issues/2031 regarding the possibility for being able to create a cloud.HttpServer from a Promise that will eventually return the http.Server. I might be naive but it seems like this could be supported with minimal code change. I've created a PR that I think will work (only looking at AWS right now, not sure yet how this might impact other Cloud providers).

Let me know what you think about this so far: https://github.com/pulumi/pulumi-cloud/pull/630

It just holds on to a single promise instance and so subsequent calls to .then just return the already instantiated server.

This would allow for integrating with application frameworks like NestJS similar to how it is demonstrated in this issue:

require('source-map-support').install();

import { Context, Handler } from 'aws-lambda';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Server } from 'http';
import { createServer, proxy } from 'aws-serverless-express';
import { eventContext } from 'aws-serverless-express/middleware';
import express from 'express';

let cachedServer: Server;
const expressApp = require('express')();

// NOTE: If you get ERR_CONTENT_DECODING_FAILED in your browser, this is likely
// due to a compressed response (e.g. gzip) which has not been handled correctly
// by aws-serverless-express and/or API Gateway. Add the necessary MIME types to
// binaryMimeTypes below
const binaryMimeTypes: string[] = [];

async function bootstrapServer(): Promise<Server> {
  const nestApp = await NestFactory.create(AppModule, expressApp);
  nestApp.use(eventContext());
  await nestApp.init();
  return createServer(expressApp, undefined, binaryMimeTypes);
}

export const handler: Handler = async (event: any, context: Context) => {
  if (!cachedServer) {
    console.log('Bootstraping server');
    cachedServer = await bootstrapServer();
  } else {
    console.log('Using cached server');
  }
  return proxy(cachedServer, event, context, 'PROMISE').promise;
};

WonderPanda avatar Oct 19 '18 14:10 WonderPanda

Very interesting! Left some feedback on the PR. Would also need to test this and validate it works for Azure as well. Thanks!

CyrusNajmabadi avatar Oct 19 '18 21:10 CyrusNajmabadi

Awesome I'll go through and clean things up. What's the best way to go about verifying things work properly on multiple clouds? Any specific test harnesses or anything that I should look at or additional tests I can add?

WonderPanda avatar Oct 19 '18 22:10 WonderPanda

Please forgive me if I am off-topic. I would appreciate it if you could point me in the right direction. I am using Nest.js for about 2 years now. It gives me a very nice developer experience. I am also reading and playing with Terraform and Pulumi for a couple of months and it looks like a great technology. I would love to see both those technologies combine to give developers who are interested in it some more responsibility on cloud infrastructure with the easiest most smooth experience possible. regardless of cloud provider, I read about some libraries that enable the publishing of your application in the form of a dockerized container but I am wondering if this is also possible for serverless deployment. I read this artivel about deploying a nest.js application as azure function and wondered if it is possible to combine Nest.js+Serverless HTTP functions deployment + Pulumi in a CI/CD setup.. even if it is not possible today I would like to know if you think this might be possible to build some library that will enable this kind of development style :) thanks in advance

danielglazer avatar Sep 08 '21 08:09 danielglazer

@danielglazer I don't have hands on experience deploying NestJS to Azure functions using Pulumi but I have a fair bit now working with AWS Lamdba in a CI/CD setup.

I ultimately moved away from using the cloud.httpServer abstraction and favored creating the lambda specifically for AWS as you have a lot more control over the entire process. I would expect that you'll have better luck using this approach with Azure Functions as well

WonderPanda avatar Sep 08 '21 20:09 WonderPanda