Как вырваться из промежуточного программного обеспечения Мартини - PullRequest
2 голосов
/ 14 марта 2020

Короче говоря, если я запускаю некоторое промежуточное программное обеспечение для http.Request и определяю, что запрос заслуживает HTTP 422, как я могу "вырваться" из цепочки промежуточного программного обеспечения, и вернуть рано без Вызов всех функций промежуточного программного обеспечения в цепочке?

Например, если у меня есть это:

func Routes(m *martini.ClassicMartini) {

    m.Get("/cp/users", mw.AsJson, mw.RequestTimer, ctr.GetMany)

}

, если я позвоню return в любом из перечисленных выше средств промежуточного программного обеспечения, насколько мне известно он по-прежнему будет вызывать все средства промежуточного программного обеспечения, зарегистрированные в цепочке, так что всегда вызывается ctr.GetMany.

есть какой-нибудь способ сделать запрос / ответ завершенным и сказать martini, чтобы он прекратил вызывать все функции в цепочке?

, если первое возвращаемое значение является целым числом, я думаю, Мартини предполагает, что это код состояния. Моя текущая лучшая догадка в соответствии с документами: https://github.com/go-martini/martini#middleware -хендлеры

мы могли бы использовать это:

m.Use(func(c martini.Context, w http.ResponseWriter){

    if reqIsMalformed() {
        http.Error(w, "Bad request because xyz", 422)
        return;
    }

    c.Next()

})

и если условие не было выполнено, мы никогда не мог позвонить c.Next()?

1 Ответ

1 голос
/ 16 марта 2020

Я провел эксперимент с роутером / промежуточным ПО, вот результаты (полезная информация в конце):

func check0() {
    return
}

func check01() int {
    return 200
}

func check02() (int, string) {
    return 200, "boop"
}

func check03() bool {
    return true
}

func check04() string {
    return "04"
}

func check1(res http.ResponseWriter) string {
    return "1"
}

func check2(c martini.Context, res http.ResponseWriter) string {
    if true {
        return "hiii"
    }
    c.Next()
    return "2"
}

func check3(c martini.Context, res http.ResponseWriter) string {
    c.Next()
    return "3"
}

func check4(res http.ResponseWriter) {
    res.Write([]byte("4"))
}

func check5(c martini.Context, res http.ResponseWriter) (int, string, string) {
    res.Write([]byte("5.0"))
    c.Next()
    return 200, "5.1x", "5.1y"
}

func finish(res http.ResponseWriter) {
    fmt.Println("in finish")
    res.Write([]byte("all done"))
}

func Routes(m *martini.ClassicMartini) {
    m.Get("/cp/meta/test/middleware0", check0, finish)
    m.Get("/cp/meta/test/middleware01", check01, finish)
    m.Get("/cp/meta/test/middleware02", check02, finish)
    m.Get("/cp/meta/test/middleware03", check03, finish)
    m.Get("/cp/meta/test/middleware04", check04, finish)
    m.Get("/cp/meta/test/middleware1", check1, finish)
    m.Get("/cp/meta/test/middleware2", check2, finish)
    m.Get("/cp/meta/test/middleware3", check3, finish)
    m.Get("/cp/meta/test/middleware4", check4, finish)
    m.Get("/cp/meta/test/middleware5", check5, finish)
    m.Get("/cp/meta/echo_runtime_config", common.AsJson, common.RequestTimer, mw.BodyToMap, ctr.GetRuntimeConfig)
}

и вот результаты, когда я нажал на api:

GET /cp/meta/test/middleware0 => 'all done'
GET /cp/meta/test/middleware01 => ''
GET /cp/meta/test/middleware03 => '<bool Value>'
GET /cp/meta/test/middleware02 => 'boop'
GET /cp/meta/test/middleware1 => '1'
GET /cp/meta/test/middleware04 => '04'
GET /cp/meta/test/middleware2 => 'hiii'
GET /cp/meta/test/middleware3 => 'all done3'
GET /cp/meta/test/middleware4 => '4'
GET /cp/meta/test/middleware5 => '5.0all done5.1x'

предполагалось добавить к этому вопросу. Итак, вот правила:

  1. , если функция промежуточного программного обеспечения возвращает что-нибудь (иначе у забавного c есть не возвращаемая подпись возврата), то никакое последующее промежуточное программное обеспечение не будет вызвано.
  2. вставка различных параметров, похоже, не имеет значения в отношении того, вызывается ли последующее промежуточное программное обеспечение (включая martini.Context, et c).
  3. Использование martini.Context.Next () Появляется полезным только для запуска ловушки после вызова всего остального промежуточного программного обеспечения.
  4. Оставшееся промежуточное программное обеспечение будет вызвано, если ничего не будет возвращено, очевидно, вам не нужно вызывать c .Next ().
  5. Если вы вернете int в качестве первого аргумента в списке возврата, он будет интерпретирован как код состояния http, второй аргумент, если он будет записан в теле. Если первый аргумент является строкой, а не int, то это будет записано в тело. Я не уверен, что третьи аргументы используются или игнорируются, но они, похоже, игнорируются.
...