many examples中有将Express用于Firebase云功能的
。在我发现的每个示例中,代码都将Express应用程序公开为单个Cloud Function:
exports.app = functions.https.onRequest(app);
对于一个人的Firebase项目功能,这意味着他们将看到一个名为“ app”的条目,并且所有Express.js HTTP侦听器的所有日志都将转到Firebase中的一个位置。这也意味着,无论Express.js应用程序有多大,Firebase都会在生产环境中为该应用程序部署一个功能。
或者,当使用firebase-functions.https.onRequest
时,对于每种导出,例如在Typescript中,您将获得单独的功能:
export const hello = functions.https.onRequest(async (req, res) => {
res.status(200).send('hello world');
});
在Firebase控制台中,我有我的hello函数以及index.js中的另一个函数:
这还意味着Firebase将为每个功能hello
和emphemeralKey
创建不同的节点/实例。
在Firebase控制台中,我将为每个功能分别记录日志。
我想使用中间件来确保将有效的身份验证令牌传递给Firebase example这样的端点云功能,但是我不希望不使用单个“应用程序”单个云功能,而希望使用在index.js中用于函数导出的专用函数。
答案 0 :(得分:1)
感谢Doug Stevenson的回答和帮助。我想提供自己的答案。
所以我的问题的答案通常是:不,你不能。
正如道格指出的那样,对于许多人的扩展需求而言,这不是问题。 Firebase最多可以创建1000个函数实例以进行扩展。
我想提供与道格稍有不同的答案,说明我将如何编写Express应用并为项目提供不同的Firebase Cloud功能:
const payment = express()
const order = express()
payment.get('/route', ...)
order.get('/route', ...)
export const payment = functions.https.onRequest(payment)
export const order = functions.https.onRequest(order)
这里的优点是我可以开始表达REST或RPC路由,例如:
另一个好处是,我可以为信用卡付款/处理之类的事情提供“测试” API和“实时” API:
// [START Express LIVE App]
// [START get user]
app.get('/user', async (req, res) => {
await handleGetUser(req, res, paymentServiceLive);
});
// [END get user]
// [START claim]
app.post('/claim', async (req, res) => {
await handleClaim(req, res, claimEmailTo);
});
// [END claim]
// [START user]
app.post('/user', async (req, res) => {
await handleUserPost(req, res, paymentServiceLive);
});
// [END user]
// [START ephemeralKey]
app.post('/ephemeralKey', async (req, res) => {
await handleEphemeralKey(req, res, paymentServiceLive);
});
// [END ephemeralKey]
// [START charge]
app.post('/charge', async (req, res) => {
await handleCharge(req, res, paymentServiceLive);
});
// [END charge]
// [START purchase]
app.post('/purchase', async (req, res) => {
await handlePurchase(req, res, paymentServiceLive);
});
// [END purchase]
//Expose Express API as a single Cloud Function:
exports.app = functions.https.onRequest(app);
// [END Express LIVE App]
// [START Express TEST App]
// [START get user]
appTest.get('/user', async (req, res) => {
console.log('appTest /user get', req);
await handleGetUser(req, res, paymentServiceTest);
});
// [END get user]
// [START claim]
appTest.post('/claim', async (req, res) => {
await handleClaim(req, res, claimEmailToTest, true);
});
// [END claim]
// [START user]
appTest.post('/user', async (req, res) => {
console.log('appTest /user post', req);
await handleUserPost(req, res, paymentServiceTest);
});
// [END user]
// [START ephemeralKey]
appTest.post('/ephemeralKey', async (req, res) => {
await handleEphemeralKey(req, res, paymentServiceTest)
});
// [END ephemeralKey]
// [START charge]
appTest.post('/charge', async (req, res) => {
await handleCharge(req, res, stripeTest);
});
// [END charge]
// [START purchase]
appTest.post('/purchase', async (req, res) => {
await handlePurchase(req, res, paymentServiceTest);
});
// [END purchase]
//Expose Express API as a single Cloud Function:np
exports.apptest = functions.https.onRequest(appTest);
// [END Express TEST App]
这使我拥有一个开发环境和一个实时环境。在我的应用程序配置文件中,我只有一个不同的API网址:
/us-central1/apptest
或
/us-central1/app
答案 1 :(得分:0)
如果只有一个Express应用程序,则无法在项目中的不同逻辑功能之间划分其路由。如果您必须尝试在多个功能之间分配负载,则可以将同一Express应用程序部署到所需的单个功能中。
const app = express()
app.get('/route1', ...)
app.get('/route2', ...)
export const f1 = functions.https.onRequest(app)
export const f2 = functions.https.onRequest(app)
// etc
现在,您可以尝试解决不同功能(及其产生的不同URL)之间的不同路由。但是您并没有固有地限制某些路由不能在不同的函数中调用。确保您的客户端正在使用您想要的功能由您决定。
如果出于性能原因尝试执行此拆分,我会考虑进行这种过早的优化。 Cloud Functions将根据需要无缝扩展您的应用程序,而不仅仅是单个服务器实例。如果您希望超过documented limits,那么像这样 这样的功能拆分可能会有助于扩展性,但是我希望这并不常见。如果不了解您的应用程序的实际,观察到的性能特征,就很难说。如果您 超出限制,请contact support来帮助您解释部署中未发生的事情。
如果在监视每个路由时发现Cloud Functions的基本日志无用,则应查看custom StackDriver logging,这将有助于您更好地组织和监视功能的不同类型的日志生成。
答案 2 :(得分:0)
有趣的讨论。
我选择相同的方法:一个“端点”(又称根路由,如“ / posts”,“ / users”)==专用的云功能(由于已经被唤起的原因,而更多的是“ µservice like”,它是对我来说,什么是“ lambda函数”。
要“干燥”我的所有功能,请导入“表达”生成器。我将Express实例配置在一处。
const express = () => {
const express = require("express");
const cors = require("cors")({ origin: true });
const morgan = require("morgan");
const helmet = require("helmet");
const app = express();
app.use(helmet());
app.use(helmet.noCache());
app.use(cors);
app.use(morgan("combined"));
return app;
};
module.exports = express;
我的“ hello”端点:
const app = require("./../../express")();
/**
* /hello
*/
app.get("/", (req, res) => {
return res.send("Hello World");
});
module.exports = app;
我的index.js(主要导出):
const helloApi = require("./api/hello");
const https = functions.region("europe-west1").https;
module.exports.hello = https.onRequest(helloApi);
似乎对我们来说很好:)