【问题标题】:How can I have multiple API endpoints for one Google Cloud Function?如何为一个 Google Cloud Function 设置多个 API 端点?
【发布时间】:2018-04-19 16:53:56
【问题描述】:

我有一个 Google Cloud 函数,其中包含要在不同路径上调用的多个模块。

我正在使用无服务器框架来部署我的功能,但它的限制是每个功能只有一个路径。

我想在一个函数中使用多个路径,就像我们在 AWS 无服务器框架中一样。

假设user 云函数将有两个路径/user/add 以及/user/remove;两条路径都应该调用相同的函数。

类似这样的:

serverless.yml

functions:
  user:
    handler: handle
    events:
      - http: user/add
      - http: user/remove

如何为一个 GCF 设置多个 API 端点?

【问题讨论】:

    标签: google-cloud-functions serverless-framework


    【解决方案1】:

    目前,在 google 中,每个函数只支持一个事件定义。 For more

    【讨论】:

      【解决方案2】:

      是的,确实没有备份 Google Cloud Functions 的实际 REST 服务。它使用开箱即用的 HTTP 触发器。

      为了解决问题,我使用我的请求负载来确定要执行的操作。在正文中,我添加了一个名为 "path" 的键。

      例如,考虑函数 USER。

      添加用户:

      {
        "path":"add",
        "body":{
          "first":"Jhon",
          "last":"Doe"
        }
      }
      

      删除用户:

      {
        "path":"remove",
        "body":{
          "first":"Jhon",
          "last":"Doe"
        }
      }
      

      如果您的操作是纯粹的 CRUD,您可以使用 request.method,它提供诸如 GETPOSTPUTDELETE 之类的动词来确定操作。

      【讨论】:

        【解决方案3】:

        GCF 目前不支持函数内的路由。因此,解决方案取决于用例,但对于大多数简单的情况,例如问题中的示例,编写一个简单的路由器是一种合理的方法,不涉及更改正常的请求格式。

        如果涉及参数或通配符,请考虑使用route-parser。以deleted answer 建议this app 为例。

        Express 请求对象有一些您可以利用的有用参数:

        • req.method 给出 HTTP 动词
        • req.path 给出不带查询字符串的路径
        • req.query解析后的key-value查询字符串的对象
        • req.body 解析后的 JSON 正文

        这里有一个简单的概念证明来说明:

        const routes = {
          GET: {
            "/": (req, res) => {
              const name = (req.query.name || "world");
              res.send(`<!DOCTYPE html>
                <html lang="en"><body><h1>
                  hello ${name.replace(/[\W\s]/g, "")}
                </h1></body></html>
              `);
            },
          },
          POST: {
            "/user/add": (req, res) => { // TODO stub
              res.json({
                message: "user added", 
                user: req.body.user
              });
            },
            "/user/remove": (req, res) => { // TODO stub
              res.json({message: "user removed"});
            },
          },
        };
        
        exports.example = (req, res) => {
          if (routes[req.method] && routes[req.method][req.path]) {
            return routes[req.method][req.path](req, res);
          }
        
          res.status(404).send({
            error: `${req.method}: '${req.path}' not found`
          });
        };
        

        用法:

        $ curl https://us-east1-foo-1234.cloudfunctions.net/example?name=bob
        <!DOCTYPE html>
              <html lang="en"><body><h1>
                hello bob
              </h1></body></html>
        $ curl -X POST -H "Content-Type: application/json" --data '{"user": "bob"}' \
        > https://us-east1-foo-1234.cloudfunctions.net/example/user/add
        {"message":"user added","user":"bob"}
        

        如果您遇到 CORS 和/或预检问题,请参阅 Google Cloud Functions enable CORS?

        【讨论】:

          【解决方案4】:

          您可以使用 Firebase 托管来重写 URL。

          在您的 firebase.json 文件中:

          "hosting": {
              "rewrites": [
                    {
                      "source": "/api/v1/your/path/here",
                      "function": "your_path_here"
                    }
              ]
          }
          

          请记住,这是一种解决方法,它有一个主要缺点:您需要为连击付费。如果您的应用必须扩展,请考虑这一点。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-03-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-12-17
            • 1970-01-01
            相关资源
            最近更新 更多