# # #go #google-cloud-platform #google-cloud-functions #middleware
Вопрос:
Что эквивалентно обработчикам промежуточного программного обеспечения в облачных функциях Google?
При стандартном подходе, как правило, я делаю:
router.Handle("/receive", middlewares.ErrorHandler(MyReceiveHandler))
А затем, в промежуточном программном обеспечении:
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()))
}
В AWS Lambda я могу добиться того же, используя, например:
func main() {
lambda.Start(
middlewares.Authentication(Handler),
)
}
Но я не смог найти способ сделать это в функциях GCP.
Как это будет работать?
Вы не могли бы мне помочь?
Ответ №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
); поэтому , если у вас есть a http.Handler
, вам нужно будет явно выбрать его ServeHTTP
метод, чтобы получить функцию ожидаемого типа. Однако этот идентификатор может быть функцией уровня пакета, методом или переменной.
Вот как вы можете адаптировать приведенный выше код для 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!")
}
Комментарии:
1. Я не думаю, что понял … не могли бы вы показать мне пример кода, пожалуйста? извините
2. Теперь я могу ясно понять, хотя моя функция возвращает ошибку, поскольку это промежуточное программное обеспечение для обработки ошибок (функция ErrorHandler типа(http.ResponseWriter, *http. Запрос) ошибка). Будет ли это все еще возможно?
3. @тьяго В вашем фрагменте кода, какова подпись
router.Handle
? Кроме того, я не вижу, что делает ErrorHandler промежуточным программным обеспечением. Он не принимает обработчик и не возвращает новый обработчик…