【问题标题】:How to configure rewrite rules inside firebase-hosting to route certain requests to cloud functions?如何在 firebase-hosting 中配置重写规则以将某些请求路由到云功能?
【发布时间】:2017-11-11 15:58:46
【问题描述】:

我有一个使用 polymer 2.0 和 polymerfire 构建的 PWA,是我的 Web 应用程序。我有一个充当云功能(微服务)的快速应用程序。 示例:exports.register=functions.https.onRequest(app);

如何添加重写规则以将 /fns/register/fns/verify 映射到上述应用程序 register

我在 cloudfunction 微服务项目中更新了我的 firebase.json 文件,但是当我运行 firebase deploy --only functions:register 时,它说没有用于部署托管配置的公用文件夹!

{
    "hosting": {
        "rewrites": [{
            "source": "/fns/**", "function": "register"
        }]
    }    
}

在原始网络应用程序中维护重写规则可能是一种选择,但恕我直言,这仍然不是理想的选择。如果我必须在我的原始 Web 应用程序中执行此操作,我也尝试过,但无法成功。以下是我在原始 Web 应用程序中更新的firebase.json

{
  "database": {
    "rules": "database.rules.json"
  },
  "hosting": {
    "public": "build/default/public",
    "rewrites": [
      {
        "source": "/fns/**",
        "function": "register"
      },
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}

【问题讨论】:

    标签: firebase google-cloud-functions firebase-hosting


    【解决方案1】:

    只为所有资源(主机、函数和数据库)维护一个项目是理想的,我认为这是管理 Firebase 项目的正确方法。

    您正试图仅更改托管服务的一个参数(重写),但它的工作方式并非如此。部署 firebase.json 时,所有其他配置都会被覆盖。所以,你得到的错误是因为 Firebase 没有查看最后一个配置文件并检查有什么不同的更新,它只是试图覆盖所有最后一个配置文件并得到一个错误,因为“public”是托管的必需参数。

    这解释了,现在您期望 Firebase 将 /fns/register 重写为 /register,但它不会发生。您的函数将收到“完整”网址/fns/register

    我认为最好的方法是创建根路由:

    var functions = require('firebase-functions');
    var express = require('express');
    
    var app = express();
    var router = express.Router();
    
    router.post('/register', registerFunction);
    router.post('/verify', verifyFunction);
    
    app.use('/fns', router);
    
    exports.fns = functions.https.onRequest(app);
    

    并将所有函数重写为fns函数:

    {
      "database": {
        "rules": "database.rules.json"
      },
      "hosting": {
        "public": "build/default/public",
        "rewrites": [
          {
            "source": "/fns/**",
            "function": "fns"
          },
          {
            "source": "**",
            "destination": "/index.html"
          }
        ]
      }
    }
    

    现在您可以使用https://<your-project-id>.firebaseapp.com/fns/register 访问您的注册功能,使用https://<your-project-id>.firebaseapp.com/fns/verify 访问您的验证功能。

    【讨论】:

    • 感谢@Marcos V 的回答。但来自 google IO 2017 的持续建议是使用微服务。因此,只有一个项目并不是我正在寻找的一个很好的解决方案。我想采用微服务风格,因为它的敏捷性、可扩展性和错误定位。因此我无法接受你的回答。
    • @Phani 您的问题标题根本没有提到单独项目的要求。也许您可以接受这个答案(它回答了您的主要问题)并提出另一个问题,即如何能够在单独的项目中维护重写规则和功能?
    • 我不能接受这是@Motin 的解决方案,因为在一个项目中维护所有托管、功能和数据库在微服务世界中并不理想。我宁愿接受托管文件只能在一个主要项目中(虽然不理想)。但是这些功能可以在任意数量的其他项目中,并且数据库可以完全在另一个项目中。这是微服务的方法,我已经在关注了。
    【解决方案2】:

    这里已经回答了这个问题Firebase Hosting with dynamic cloud functions rewrites

    我同意你的观点,最好将 SPA 保留在一个项目中,将微服务保留在另一个项目中,但 @Marcos V 关于使用根函数是正确的

    【讨论】:

      【解决方案3】:

      我对 Marcos V 的答案投了赞成票。但我不能真正接受这个答案。主要是因为在微服务世界中,您不会在一个地方创建具有所有功能的单体。您宁愿分解成可管理的块,并为应用程序创建尽可能多的必要/合理的适当微服务。

      使用当前的 firebase-hosting 设置,您必须在一个项目中单独拥有主机配置文件。此外,托管应在一个项目中,因为与您的站点相关的所有 HTML、JS、CSS 将具有相互依赖关系,因此是不可分割的(至少到目前为止)。

      而云功能最好被视为服务于明确目的的微服务,因此需要根据需要位于单独的项目/微服务中。可以使用firebase deploy --only functions:YOUR_FN_NAME 轻松部署

      当您需要为新的云功能微服务添加映射时,请继续在主托管应用程序中更改路由并进行部署。通过这种方法,我们至少可以让后端部分成为微服务。

      现在,在同一个托管应用程序或单独的项目中维护数据库规则留给设计人员,他们可以根据自己的用例做出决定。

      【讨论】:

      • 我认为您误解了服务和项目之间的区别。无需将微服务分解为单独的项目,就像在不同的笔记本电脑上编写每个项目一样。这不是为了分离而分离。
      • @RobHogan 我不是为了分离而提倡分离!当谈到微服务时,至少我们遵循的做法是根据它们正在处理的业务功能来区分它们,而不仅仅是它们正在处理的实体。有了这个,当相应的业务功能有更新时,我们就可以获得本地化更改和测试需求所需的分离。这对我们处理多个关注点的团队来说效果很好,并大大减少了我们的测试工作!将所有后端逻辑放在一个单一的整体服务中,总有一天会咬到你!
      • 单独的 GCP 项目与这些无关。 GCP 可以在一个项目中托管任意数量的微服务,通常您只需要出于计费原因或便于访问管理而拆分项目。但是,如果您找到了适合您的系统,那就够公平了,祝您好运。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-01
      • 1970-01-01
      • 2021-04-14
      • 2019-10-17
      • 1970-01-01
      • 2021-05-04
      • 2021-04-29
      相关资源
      最近更新 更多