-
-
Notifications
You must be signed in to change notification settings - Fork 7.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deploying to google cloud functions #238
Comments
I dream with a I think that for AWS lambda, using this project https://github.com/awslabs/aws-serverless-express as a base, it can be done |
Hi @ArsalaBangash, |
Hi @ArsalaBangash, |
Hi @kamilmysliwiec, We are finalizing our first project with Typescript / Nodejs stack that will run on AWS Lambda. We used the serverless framework, Sequelize for access to SQL databases, and Inversify as DI container. I recently discovered NestJS, and this framework look very interesting to better structure our Typescript / Nodejs projects (currently PHP / Symfony / DDD). However, I did not manage to use it with AWS Lambda :( It might be interesting to have a small recipe / section on the website to help newbie as me ^^ Serverless is a very trending word! ;) Thanks |
I have tried the "aws-serverless-express" with nestjs, and it works from time to time. It works at the first request, and then the subsequent requests do not work (aws lambda timeout). And then a while later, it works again for a request. |
@popofr13 @Vincent-Pang @jgordor this is probably not the best way, but at least as a POC it deploys successfully to lambda (uses serverless-plugin-typescript and serverless-offline plugins) handler.ts import * as serverless from 'aws-serverless-express';
import { NestFactory } from '@nestjs/core';
import { ApplicationModule } from './src/app.module';
const express = require('express')();
module.exports.nest = async (event, context) => {
const app = await NestFactory.create(ApplicationModule, express);
await app.init();
const server = serverless.createServer(express);
serverless.proxy(server, event, context);
}; |
@danitt I'm wondering how good it is using nest with aws lambda? Did you run to any problems? |
@chanlito literally just got basic deployment working a few minutes ago, but hoping to test it out on a side project this month - I have big hopes for it, Angular-style architecture in the backend sounds amazing |
@danitt Great, my code is similar to yours, and I found that it works after upgrading the nest to the latest version. Thank you for your POC. btw, anyone has ideas to make the log in aws cloudwatch more pretty?
|
@Vincent-Pang can you show us how you implemented it, I'm curious as for logging, could take inspiration from this: |
Sorry...i'm trying to deploy nodeJS used as graphQL-api gateway to a lambda function...Did someone try to deploy in a lambda? Is there a little guide on it? Thanks!!! |
@danitt I've managed to use your solution to get things working in serverless-offline and it deploys just fine, but I'm getting 502 bad gateway when trying to access to the deployed route. Did you encounter this at all in your development? My code looks like this: Nested.jsimport { Callback, Context, Handler } from 'aws-lambda';
import { NestFactory } from '@nestjs/core';
import { Module } from '@nestjs/common';
import * as serverless from 'aws-serverless-express';
const express = require('express')();
import { Get, Controller, Req } from '@nestjs/common';
@Controller('nested/messages')
class AppController {
@Get()
root(@Req() req) {
return {
text: 'Hello World!'
};
}
}
// Was testing here to see if the issue may have been related to the `dev` prefix that is put on the route when deployed to Lambda
@Controller('dev/nested/messages')
class AppController2 {
@Get()
root(@Req() req) {
return {
text: 'Hello World!!!!'
}
}
}
@Module({
imports: [],
controllers: [AppController, AppController2],
components: [],
})
class AppModule {}
export const handler: Handler = async (event: any, context: Context, callback: Callback) => {
const app = await NestFactory.create(AppModule, express);
await app.init();
const server = serverless.createServer(express);
serverless.proxy(server, event, context);
}; serverless.ymlservice: service
plugins:
- serverless-plugin-typescript
- serverless-offline
- serverless-plugin-include-dependencies
provider:
name: aws
runtime: nodejs8.10
custom:
services: src/services
Nested: ${self:custom.services}/Nested
package:
individually: true
include:
${self:custom.Nested}.ts
functions:
nested:
handler: ${self:custom.Nested}.handler
events:
- http:
cors: true
path: nested/{proxy+}
method: any |
@danitt (and anyone else running into this issue) Seems I've figured it out! Turns out it's an async incompatibility with I resolved this by falling back to traditional promise behavior instead of my precious async/await: export const handler: Handler = (event: any, context: Context, callback: Callback) => {
NestFactory.create(AppModule, express).then(app => {
app.init().then(() => {
const server = serverless.createServer(express);
return serverless.proxy(server, event, context);
});
});
}; I'm still planning on finding a way to move the |
@jonnyasmar The following is one way to move the import { Context, Handler } from 'aws-lambda';
import { NestFactory } from '@nestjs/core';
import { ApplicationModule } from './app.module';
import { Server } from 'http';
import * as serverless from 'aws-serverless-express';
const express = require('express')();
let cachedServer: Server;
function bootstrapServer(): Promise<Server> {
return NestFactory.create(ApplicationModule, express)
.then(app => app.init())
.then(() => serverless.createServer(express));
}
export const handler: Handler = (event: any, context: Context) => {
if (!cachedServer) {
console.log('Bootstraping server');
bootstrapServer().then(server => {
cachedServer = server;
return serverless.proxy(server, event, context);
});
} else {
console.log('Using cached server');
return serverless.proxy(cachedServer, event, context);
}
}; It appears to make response times quicker for subsequent requests, but I've not tested this in any great detail. |
Thanks for the reply @djeley ! This is almost exactly how I ended up handling it :D let served;
const createServer = () => {
return new Promise(resolve => {
NestFactory.create(AppModule, express).then(app => {
app.init().then(() => {
resolve(serverless.createServer(express));
});
});
});
};
export const handler: Handler = (event: any, context: Context) => {
if (served) return serverless.proxy(server, event, context);
else
createServer().then(server => {
served = server;
return serverless.proxy(served, event, context);
});
}; |
@djeley Really like that shorthand for your promise chaining btw. Totally stealing that 😈 |
Reopening this issue. I think we should provide a guide in the documentation 🙂 |
What are the real benefits from deploy the express app as lambda ? |
@szkumorowski scalability, huge cost savings (with exceptions), no server-side config/maintenance, enforces statelessness, to name a few |
We're working on the async support in aws-serverless-express. For now you can patch it yourself; see CodeGenieApp/serverless-express#134 (comment) |
Thanks @brettstack 🙂 |
@kamilmysliwiec - looking forward to your apex documentation on this! very exciting |
Let's track this issue in the docs repo: nestjs/docs.nestjs.com#96 |
For those of you looking to deploy to APIGateway (proxy+) + Lambda, I just figured it out (Thanks @brettstack for all your work). Took me some time to piece all the parts together, hope this helps someone else out.
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;
}; For extra credit, you can add the following to your
|
Thank you all. I'm currently looking for a way to deploy Apollo Server to lambda as well (https://www.apollographql.com/docs/apollo-server/v2/deployment/lambda.html) -- any tips? |
@picosam A little off topic, but this might help you https://medium.com/mistergreen-engineering/apollo-server-in-google-cloud-functions-using-nestjs-a5a64486bc8a |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
I'm building the backend for a startup. We were initially going to deploy on the google app engine but now the team has decided to switch over to cloud functions. I've already built a great deal of the backend using the nestjs framework and I love it. Is there any way I could use the nest framework in conjunction with google cloud functions?
The text was updated successfully, but these errors were encountered: