英文:
HTTP Middleware and Google Cloud Functions
问题
在Google Cloud Functions中,与中间件处理程序相当的是云函数的中间件。以下是一个示例:
首先,在云函数中定义处理程序:
def my_receive_handler(request):
# 处理请求的逻辑
return 'Response'
然后,定义中间件函数:
def error_handler_middleware(request):
try:
response = my_receive_handler(request)
return response
except Exception as e:
# 处理错误的逻辑
print(f"An error occurred: {e}")
return 'Internal Server Error', 500
最后,在云函数中使用中间件:
def main(request):
return error_handler_middleware(request)
这样,当请求进入云函数时,会先经过中间件函数进行处理,然后再传递给实际的处理程序。如果在中间件函数中发生错误,将会返回一个内部服务器错误的响应。
希望对你有所帮助!
英文:
What’s the equivalent to middleware handlers in Google Cloud Functions?
In standard approach, normally I do:
router.Handle("/receive", middlewares.ErrorHandler(MyReceiveHandler))
And then, in the middleware:
type ErrorHandler func(http.ResponseWriter, *http.Request) error
func (fn ErrorHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
err := fn(w, r)
if err == nil {
return
}
log.Printf("An error accured: %v", err)
clientError, ok := err.(errors.BaseError)
if !ok {
w.WriteHeader(500)
return
}
w.WriteHeader(clientError.GetStatusCode())
w.Write([]byte(clientError.Error()))
}
In AWS Lambda, I can achieve the same thing using, for example:
func main() {
lambda.Start(
middlewares.Authentication(Handler),
)
}
But I could not find a way to do this in GCP Functions.
How would it work?
Can you help me?
答案1
得分: 1
假设你在开发环境中有以下的服务器代码:
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
http.Handle("/", MiddlewareFinalMsg(" Goodbye!", http.HandlerFunc(HelloWorld)))
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal(err)
}
}
func MiddlewareFinalMsg(msg string, h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h.ServeHTTP(w, r)
fmt.Fprint(w, msg)
})
}
func HelloWorld(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
fmt.Fprint(w, "Hello, World!")
}
据我所知,GCF 要求其入口点为类型为 func(http.ResponseWriter, *http.Request)
的导出标识符(不是 http.HandlerFunc
,也不是 http.Handler
)。因此,如果你有一个 http.Handler
,你需要显式地选择其 ServeHTTP
方法以获得预期类型的函数。然而,该标识符可以是一个包级函数、一个方法或一个变量。
以下是如何将上述代码适应于 GCF 的方法:
package p
import (
"fmt"
"net/http"
)
// 将 F 作为 GCF 的入口点
var F = MiddlewareFinalMsg(" Goodbye!", http.HandlerFunc(HelloWorld)).ServeHTTP
func MiddlewareFinalMsg(msg string, h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h.ServeHTTP(w, r)
fmt.Fprint(w, msg)
})
}
func HelloWorld(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
fmt.Fprint(w, "Hello, World!")
}
以上是将代码适配为 GCF 的方法。
英文:
Let's say you start with the following server code in your development environment:
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
http.Handle("/", MiddlewareFinalMsg(" Goodbye!", http.HandlerFunc(HelloWorld)))
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal(err)
}
}
func MiddlewareFinalMsg(msg string, h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h.ServeHTTP(w, r)
fmt.Fprint(w, msg)
})
}
func HelloWorld(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
fmt.Fprint(w, "Hello, World!")
}
As far as I can tell, GCF requires its entry point to be an exported identifier of type func(http.ResponseWriter, *http.Request)
(not http.HandlerFunc
, not http.Handler
); therefore, if you have a http.Handler
, you'll need to select its ServeHTTP
method explicitly to obtain a function of the expected type. However, that identifier can be a package-level function, a method, or a variable.
Here is how you can adapt the code above for GCF:
package p
import (
"fmt"
"net/http"
)
// use F as your GCF's entry point
var F = MiddlewareFinalMsg(" Goodbye!", http.HandlerFunc(HelloWorld)).ServeHTTP
func MiddlewareFinalMsg(msg string, h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h.ServeHTTP(w, r)
fmt.Fprint(w, msg)
})
}
func HelloWorld(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
fmt.Fprint(w, "Hello, World!")
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论