我怎样才能为一个 Google Cloud Function 设置多个 API 端点



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

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

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

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

像这样:

serverless.yml

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

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

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

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

例如,考虑函数 USER。

要添加用户:

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

要移除用户:

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

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

您可以使用 Firebase Hosting 重写网址。

在您的 firebase.json 文件中:

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

请记住,这是一种解决方法,它有一个主要缺点:您将为双重打击付费。如果你的应用必须缩放,请考虑这一点。

您可以在不同的运行时中编写函数。Node.js运行时使用 Express 框架。因此,您可以使用其路由器在单个功能中构建不同的路由。

添加依赖项

npm install express@4.17.1

以下示例使用打字稿。请遵循这些准则来启动打字稿项目。

// index.ts
import { HttpFunction } from '@google-cloud/functions-framework';
import * as express from 'express';
import foo from './foo';
const app = express();
const router = express.Router();
app.use('/foo', foo)
const index: HttpFunction = (req, res) => {
  res.send('Hello from the index route...');
};
router.get('', index)
app.use('/*', router)
export const api = app
// foo.ts
import { HttpFunction } from '@google-cloud/functions-framework';
import * as express from 'express';
const router = express.Router();
const foo: HttpFunction = (req, res) => {
  res.send('Hello from the foo route...');
};
router.get('', foo)
export default router;

要部署运行:

gcloud functions deploy YOUR_NAME 
--runtime nodejs16 
--trigger-http 
--entry-point api 
--allow-unauthenticated

目前,在谷歌中只允许每个函数支持一个事件定义。欲了解更多信息

> Express 可以与 npm i express 一起安装,然后导入并或多或少地像往常一样使用来处理路由:

const express = require("express");
const app = express();
// enable CORS if desired
app.use((req, res, next) => {
  res.set("Access-Control-Allow-Origin", "*");
  next();
});
app.get("/", (req, res) => {
  res.send("hello world");
});
exports.example = app; // `example` is whatever your GCF entrypoint is
<小时 />

如果由于某种原因无法选择 Express 或用例非常简单,则自定义路由器可能就足够了。

如果涉及参数或通配符,请考虑使用 route-parser 。删除的答案建议将此应用程序作为示例。

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

  • req.method给出 HTTP 动词
  • req.path,它给出没有查询字符串的路径
  • req.query已分析的键值查询字符串的对象
  • 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(/[Ws]/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 是否启用 CORS?

最新更新