loopbackio / loopback-next

LoopBack makes it easy to build modern API applications that require complex integrations.
https://loopback.io
Other
4.95k stars 1.07k forks source link

Serverless support #257

Closed ritch closed 3 years ago

ritch commented 7 years ago

I should be able to run my loopback.next apps in the following contexts:

  1. Inside an action within a serverless architecture (eg. whisk, lambda)
  2. As a gateway to a serverless backend
  3. An event provider
ZepAviator commented 7 years ago

There is a distinct lack of a good framework around "Serverless" options. Obviously, there is a desire to keep serverless functions lean in an attempt to speed up cold-start times.

It would be VERY interesting to utilize something like Webpack to create build folders to match your serverless architecture (lambda, whisk, google functions, etc...). Similar to what Google has been working on with the PRPL pattern for front-end architecture: https://developers.google.com/web/fundamentals/performance/prpl-pattern/

onel0p3z commented 7 years ago

@ritch can you please provide a good example where one would want to run a loopback.next app in a handler or action within a serverless arch? I'm trying to understand in order to come up with good examples.

jonathan-casarrubias commented 7 years ago

@onel0p3z here is a good documentation that deeply explains the serverless architecture with good examples

https://martinfowler.com/articles/serverless.html#ACoupleOfExamples

onel0p3z commented 7 years ago

@jonathan-casarrubias thanks for your response and the resource! Maybe I can rephrase the question to make it more clear. I am familiar with the serverless arch and have used diff providers. My question was targeted more to understand where can loopback.next play a role in the handler of a lambda function for instance. as a router for other actions? CQRS? Hope i explained myself better 👍

jonathan-casarrubias commented 7 years ago

@onel0p3z thanks for clarifying now it is more clear, though I guess we will need to wait for the official answer for that question since I'm unaware of the plans for this implementation.

I apologize for the confusion.

Cheers Jon

onel0p3z commented 7 years ago

@jonathan-casarrubias thanks and no need to apologize 👍 😄 ideally, with a clear use case, I'd like to come up with examples of it for different providers (aws, azure, gcloud, etc.)

Brian-McBride commented 7 years ago

@onel0p3z I see a use of leveraging loopback in a light form for serverless functions. Obviously a function is typically tied to one event.

Even within a Lambda, Google Function, etc... there are common needs. Authentication, Access Management, Data connections, external API calls, common middleware, etc... A lot of stuff that frameworks like Loopback provide currently.

But, yeah, ideally in these new functional services you want to keep your code light for cold-starts. Still, I find that my package.json list grows and I'm slowly building up blueprints for my functions that are looking more and more like "loopback light" (sort of).

Use case: Single codebase for multiple functional deployments providing unified model references, unified data connectors, unified settings, etc... So if I have a lambda listening to an event and I update a database and fire off an API call, I'm using the same shared codebase that another lambda using to handle database updates (which, in this case is triggered by the first lambda). We both have a common mapping of that database's structure due to the common loopback models.

bajtos commented 6 years ago

I am closing this issue because we are not going to have time to work on this in the next 6-9 months. However, we are happy to accept a pull request contributing this feature.

voltuer commented 4 years ago

It's been over 2 years since this discussion stopped and there appear to be no answer from IBM Strongloop about this yet. Serverless is today way more popular than it was in 2017 and there's still no framework solution for it. I think Loopback has been the de-facto framework for NodeJS since its conception as it has virtually no competition, and would love to see some interest from their side on this topic.

achrinza commented 4 years ago

Thanks @sebolio for bringing the issue to our attention.

it’s definitely been a while and I agree it’s good to revisit this.

I’ve re-opened the issue so that we can continue discussion.

Unfortunately I’m not too sure how to go forward with serverless for LoopBack 4, and will need to read up more first.

In the mean time, the core maintainers may have some new ideas to chime in.

8secz-johndpope commented 4 years ago

to accommodate millions of users on our system - we need to be able to scale up systems / api end point capacity. aws lambda / serverless can do this out of the box without much (any?) thought - and then you pay per cpu usage / no servers / no web farms / no load balancing pools / health checks / no pm2 / no process monitoring....

Loopback needs to strive to play nicelessly in this space - just bootup quickly - accept the api request - process - and spit out result. @botbits created this repo a long time back - I'm yet to test it out https://github.com/botbits/serverless-loopback

UPDATE this article sums things up nicely https://medium.com/smac-4u/serverless-loopback-9ff0d6fa539d

@marcelobern Current thinking is to go aws lambda + swift https://github.com/swift-aws https://github.com/swift-sprinter/aws-serverless-swift-api-template/blob/master/Products/Sources/ProductService/ProductService.swift Hoping it's not a complete re-write.

marcelobern commented 4 years ago

@8secz-johndpope now that lb4 seems to have caught up to the key lb3 feature set and with lb3 in Maintenance LTS I am gearing up to look into creating a lb4 serverless based on the work done for lb3-serverless.

As I am reading up on lb4 I am starting to put together a plan and would be happy to get input from the lb4 community and collaborate on the development either as a contribution to standard lb4 or an external extension.

The lb3-serverless work was primarily showcasing the power of pairing up lb3 and serverless framework, and as such focused mainly on tying up the Lambda handler into the lb3 express instance.

For a minimum (and useful) capability as it relates to lb4, I would offer that the following is a good starting point:

Would love to hear any other needs the community came across and hear ideas on better approaches to tackle the capabilities listed above from folks more experienced that I am on lb4 ;-)

marcelobern commented 4 years ago

@8secz-johndpope thanks for sharing your direction around swift. I just published an update to serverless-loopback including a loopback 4 example (using express).

@achrinza seems like the direction you all are taking is tackling this from a webpack perspective only.

Based on what I learned during my brief exploration of options, I think it would be really powerful to have loopback4 be an easy way for serverless to deploy different granularity of functions (I am not sure if this is already possible with the current loopback 4 capabilities).

Here is an example showing what I mean by "different granularity of functions":

functions:
  defaultController: # check [1] for a working example
    handler: dist/lambda-wrapper.handler
    events:
      - http: ANY /
      - http: 'ANY {proxy+}'
  controllerAbc: # mocked, still needs wrapper to work in serverless (e.g. AWS Lambda)
    handler: dist/controllers/abc.controller
    events:
      - http:
          path: /abc
          method: ANY
  ping: # mocked, still needs wrapper to work in serverless (e.g. AWS Lambda)
    handler: dist/controllers/ping.controller.PingController.ping
    events:
      - http:
          path: /ping
          method: get

[1] 'botbits/serverless-loopback#15'

Would love to hear any thoughts around feasibility of the above with current capabilities.

ihiteshgupta commented 4 years ago

I just wrote an article to use Loopback 4 in AWS Lambda without express composition with easy setup. Link to article and also there is an example repo for it. Link to Repo Also, I have done AWS Secrets Manager implementation for the same to get config on runtime. For this, you can simply change this code in lambda.js.

const AWS = require('aws-sdk');

const application = require('./dist');
const awsServerlessExpress = require('aws-serverless-express');
let configs;
const app = new application.Lb4LambdaBoilerplateApplication({
  rest: {
    openApiSpec: {
      setServersFromRequest: true,
    },
  },
});
const server = awsServerlessExpress.createServer(app.restServer.requestHandler);

async function getConfig() {
  return new Promise((resolve, reject) => {
    const client = new AWS.SecretsManager({
      region: process.env.PINPOINT_REGION,
    });
    client.getSecretValue({SecretId: `${process.env.CONFIG_KEY}`}, function(err, data) {
      if (err) {
        reject(err);
      } else {
        resolve(data.SecretString);
      }
    });
  });
}

const setEnv = async () => {
  configs = JSON.parse(await getConfig());
  Object.keys(configs).forEach(key => {
    process.env[key] = configs[key];
  });
};

exports.handler = async (event, context) => {
  if (!configs) {
    await setEnv();
  }
  await app.boot();
  return awsServerlessExpress.proxy(server, event, context, 'PROMISE').promise;
};

In this implementation, I am passing configs through env during runtime you can use configs in any other way also.

stale[bot] commented 3 years ago

This issue has been marked stale because it has not seen activity within six months. If you believe this to be in error, please contact one of the code owners, listed in the CODEOWNERS file at the top-level of this repository. This issue will be closed within 30 days of being stale.

stale[bot] commented 3 years ago

This issue has been closed due to continued inactivity. Thank you for your understanding. If you believe this to be in error, please contact one of the code owners, listed in the CODEOWNERS file at the top-level of this repository.