如何从 GCP 中的另一个 Go 云函数调用一个 Go 云函数

How to call a Go Cloud Function from another Go Cloud Function in GCP

目标:我想重用两个带有 HTTP 触发器的 Go 函数中的许多 Go 函数。

我尝试过的方法和重现问题的步骤:

  1. 在 GCP 中,创建一个新的 Go 1.11 Cloud Function,HTTP 触发器
  2. 命名:MyReusableHelloWorld
  3. function.go 中粘贴:
package Potatoes

import (   
    "net/http"
)


// Potatoes return potatoes
func Potatoes(http.ResponseWriter, *http.Request) {

}
  1. go.mod 中粘贴:module example.com/foo
  2. 在要执行的函数中,粘贴:Potatoes
  3. 点击部署。有效。
  4. 在 GCP 中创建另一个 Go 无服务器函数
  5. 功能中。去吧,粘贴这个:
// Package p contains an HTTP Cloud Function.
package p

import (
    "encoding/json"
    "fmt"
    "html"
    "net/http"
    "example.com/foo/Potatoes"
)

// HelloWorld prints the JSON encoded "message" field in the body
// of the request or "Hello, World!" if there isn't one.
func HelloWorld(w http.ResponseWriter, r *http.Request) {
    var d struct {
        Message string `json:"message"`
    }
    if err := json.NewDecoder(r.Body).Decode(&d); err != nil {
        fmt.Fprint(w, "error here!")
        return
    }
    if d.Message == "" {
        fmt.Fprint(w, "oh boy Hello World!")
        return
    }
    fmt.Fprint(w, html.EscapeString(d.Message))
}
  1. go.mod 中粘贴:module example.com/foo
  2. 在要执行的函数中,粘贴:HelloWorld
  3. 点击部署。 它不起作用。 你有错误: unknown import path "example.com/foo/Potatoes": cannot find module providing package example.com/foo/Potatoes

为了module/packages导入我也试过各种组合。 我试过没有 example.com/ 部分。

其他小问题: 我想重用的函数可以都在同一个文件中,并不真的需要任何触发器,但似乎没有触发器是不可能的。

无法实现目标的相关问题和文档:

  1. https://github.com/golang/go/wiki/Modules 节 go.mod

很可能控制台中定义的每个云函数都是相互独立的。如果你想重用代码,最好按照下面的文档来构建它,然后使用 gcloud 命令部署它。

https://cloud.google.com/functions/docs/writing/#structuring_source_code

您正在混合使用:包管理和功能部署。

当你部署一个Cloud Function时,如果你想(重新)使用它,你必须使用http包调用if。

如果您构建了一个要包含在源代码中的包,则必须依赖包管理器。使用 Go,Git 存储库,如 Github,是实现此目的的最佳方式(不要忘记执行发布并按照 Go mod 的预期命名它:vX.Y.Z)

如果没有更多的工程和封装,您的代码将无法工作 publication/management。

我实现了同样的事情,但使用了 Dockerfile,我对我在 Cloud 运行 中的代码表示遗憾(如果你不是面向事件的,而只面向 HTTP,我推荐你这样做。我写了一个 comparison on Medium)

  • 根目录
    • go.mod
    • pkg/foo.go
    • pkg/go.mod
    • service/Helloworld.go
    • service/go.mod

在我的 helloworld.go 中,我可以重复使用包 foo。为此,我在我的 service/go.mod 文件

中执行此操作
module service/helloworld

go 1.12

require pkg/foo v0.0.0

replace pkg/foo v0.0.0 => ../pkg

然后当你构建你的容器时,你从根目录 运行 你的 go build service/Helloworld.go

您不能从另一个云函数中调用一个云函数,因为每个函数都独立地位于自己的容器中。

因此,如果您想部署具有无法从包管理器下载的依赖项的函数,您需要将代码放在一起,例如 here and deploy using the CLI