Access to aws-lambda context when running nodejs + expressjs - node.js

I'm, just starting out with AWS-Lambda, AWS-API Gateway and ExpressJs. I'm having trouble finding how the AWS-Lambda "context" is available in my "ExpressJs" application.
I'm using:
AWS-Lambda
AWS-API Gateway
NodeJs v4.3.2
ExpressJs 4.14.1
ClaudiaJs 2.7.0
In Aws Lambda I use aws-serverless-express to receive the API-Gateway request and initialize the node application. The following is the structure I have found from different tutorials, etc
lambda.js (Initiated from API-Gateway. Supplying the "context" variable in the call to "app.js")
'use strict'
const awsServerlessExpress = require('aws-serverless-express')
const app = require('./app')
const server = awsServerlessExpress.createServer(app)
exports.handler = (event, context) => awsServerlessExpress.proxy(server, event, context)
The core of my app.js express is:
var express = require('express');
...
var app = express();
...
app.use('/', index);
...
module.exports = app;
My questions:
Is there a way to access the AWS-Lambda "context" with this
structure?
If not, what would be the best "pattern" to make it available?
Any input appreciated.

You need to add middleware included in the aws-serverless-express package which exposes the event and context objects. You add it like this:
const awsServerlessExpressMiddleware = require('aws-serverless-express/middleware')
app.use(awsServerlessExpressMiddleware.eventContext())
Once this middleware is configured the event and context objects will be added to the request. You access those objects like so:
var event = req.apiGateway.event;
var context = req.apiGateway.context;

Related

React not recognizing Express

In my jsx file, I have the following:
var express = require('express');
var myExpress = express();
var http = require('http');
var app = http.createServer(myExpress);
var { Server } = require("socket.io");
var myio = new Server(app);
However, the browser says "Uncaught TypeError: express is not a function"
I have tried importing express with an import statement, as well as making my project a module in my package.json. What is weird is that when I use the same code in a regular js file in the same folder, it works perfectly well. This code was the code in every single one of the tutorials, so I am at a loss. Thank you.
Express is node framework you can't use it in react.
I think you need https://v5.reactrouter.com/web/guides/quick-start

How to set custom Cloud Functions Path

Let's say I want a cloud function to have a path such as:
https://[MY_DOMAIN]/login/change_password
How do I achieve the "login/" part in Node?
Or even something more complicated such as
login/admin/get_data
?
I tried using
module.exports = {
"login/change_password" = [function]
}
But I got an error when deploying and "change_password" was omitted, so it only tried to deploy a "login" function.
Another thing I tried was using express routers but that resulted in only deploying a single function, which routed to the right path (e.g. myfunction/login/change_password) which is problematic as I have to deploy in bulk every time and can't deploy a function individually.
If you want the flexibility to define routes (paths) that are more complex than just the name of the function, you should provide an Express app to Cloud Functions. The express app can define routes that add path components to the base name of the function you export from index.js. This is discussed in the documentation for HTTP functions. For example:
const functions = require('firebase-functions');
const express = require('express');
const app = express();
app.get('/some/other/path', (req, res) => { ... });
exports.foo = functions.https.onRequest(app);
In that case, all your paths will hang off of the path prefix "foo".
There is also an official samples illustrating use of Express apps: https://github.com/firebase/functions-samples/tree/master/authorized-https-endpoint
Thanks to the discussion with Doug Stevenson I was able to better phrase my question and find that it was already answered in this question.
So this would be an example of my implementation:
const functions = require('firebase-functions');
const express = require('express');
const login = require('./login.js');
const edit_data = require('./edit-data.js');
const login_app = express();
login_app.use('/get_uuid', login.getUUID);
login_app.use('/get_credentials', login.getCredentials);
login_app.use('/authorize', login.authorize);
const edit_data_app = express();
edit_data_app.use('/set_data', edit_data.setData);
edit_data_app.use('/get_data', edit_data.getData);
edit_data_app.use('/update_data', edit_data.updateData);
edit_data_app.use('/remove_data', edit_data.removeData);
exports.login = functions.https.onRequest(login_app);
exports.edit_data = functions.https.onRequest(edit_data_app);
My takeaway from this is that there is a one-to-one Express app to HTTP function correspondence, so if I wanted to have 3 different functions I would need 3 Express apps.
A good balance is to have one app and one function per module (as shown above), which also means you can separate out your functions across several modules/javascript files for ease of maintenance.
In the above example, we can then trigger those HTTP functions using
https://[DOMAIN]/login/get_uuid/
or, from the firebase functions shell
login.get("/get_uuid")

How can my client get application configuration from the server when using Webpack?

I'm adding Webpack to a Node/Express app that previously used RequireJS. When the client needed some configuration from the server, we previously used a custom Express route that retrieved specific configs as JSON:
server/index.js - Set up Express routes for config files
const app = express();
const configRouter = express.Router();
configRouter.get('/some-config.json', (req, res) => {
const someConfig = {
prop1: getProp1(),
prop2: getProp2()
}
res.json(someConfig);
}
app.use('/config', configRouter);
client/controller.js - Use/config/some-config.json during initialization
define(['text!/config/some-config.json'], function(SomeConfig) {
// do something with SomeConfig
});
But removing RequireJS means I can no longer retrieve the JSON this way as a dependency. And it's not static JSON either, so it's not as simple as just placing it alongside client code and importing it.
So what is the best way to do this with Webpack? Any help greatly appreciated. Thanks!

Instantiating express

I have an issue where I need to load express like this:
var express = require('express');
var app = express();
In order to get .static to work:
app.use(express.static(__dirname+'views'));
Any reason why I can't use shorthand:
var app = require('express')();
When I try the short hand it says express.static is undefined and my script won't run. Is this just a feature that's not supported by express?
Any reason why I can't use shorthand:
var app = require('express')();
If you considered this statement from your script,
app.use(express.static(__dirname+'views'));
you are using static method of express.In order to use this method,you must import express first and store it in some variables like u did
var express = require('express');
From express#express.js
exports.static = require('serve-static');
static defined at class level.
then instantiate it
like this
var app = express();
to get the access to object level(prototype) method and properties like
app#use app#engine etc.
From express#application //line no 78
EDIT :
but then why can't I use app.static if I did var app = require('express')();
As I said,.static is the class level method and not the instance/object(prototype) level.
So,by var app = require('express')()
you will get express instance / object (prototype) which dont have app.static method.So,you can't use.
Read more javascript-class-method-vs-class-prototype-method
This will work: const app = (() => require('express'))()();
But you still need express itself, so there literally is no real point to requiring twice.

Can I pass variable to required file?

In express, I'm trying to move my minification to a requierd file:
app.js:
var app = express();
var minify = require("./minify.js");
In that file I try to set my template engine.
minify.js:
var app = express();
app.engine('html', mustacheExpress());
Later when I try to use to use the rendering engine in app.js, I get the error that no template-engine is set. It works if I run it all in the same file. I think the problem is that I declare the app-variable twice. How can I pass the app-variable into minify.js?
The problem is that you define new app variable, and you currently instantiate brand new express instance by calling express().
What you need to do is start using functions so that you can pass params (there are other methods too, but this is one that will work for you):
// app.js
var app = express();
var minify = require('./minify'); // don't include .js!
minify(app); // CALL the function that minify.js exports, passing params
// minify.js
module.exports = function(app) {
// because app comes as a parameter, it's the very same you've created in app.js
app.engine('html', mustacheExpress());
}
Again, there are many different methods and maybe proper approaches, depending on what you want to do, but this will do the job in your case. Read more about NodeJS and it's require system.
You can pass 'app' from app.js to your minify by using function in your module like Andrey said. You can do it like this too for example :
minify.js
module.exports = {
setAppEngine : function(app) {
app.engine( [...] );
}
}
And calling it like this in your app.js:
app.js
var app = express();
var minify = require("./minify.js").setAppEngine(app);
This solution is very useful because you can set and call others methods in minify.js. For example, you can do with the same code in minify.js:
app.js
var app = express();
var minify = require("./minify.js");
minify.setAppEngine(app);

Resources