亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

總是嘗試返回相同的響應結構時,如何最小化 Go Mux 中的重復代碼?

總是嘗試返回相同的響應結構時,如何最小化 Go Mux 中的重復代碼?

Go
萬千封印 2023-01-03 11:30:28
我有大量類似于以下代碼片段的代碼,我只是嘗試填充我的響應結構、json 編組輸出、設置狀態代碼并返回結果:if err := json.NewDecoder(r.Body).Decode(&user); err != nil {            response := responses.UserResponse{                Status:  http.StatusBadRequest,                Message: "error",                Data:    map[string]interface{}{"error": err.Error()},            }            rw.WriteHeader(http.StatusBadRequest)            errRes, _ := json.Marshal(response)            rw.Write(errRes)            return        }我試圖創建一個接收r變量(request.http)的函數來接收正文以及響應的狀態代碼。但注意到我必須再次檢查函數外部的錯誤代碼,然后再次執行相同的響應創建流程。Go 專家如何盡量減少像這樣的代碼重復?首先有這樣的代碼重復可以嗎?
查看完整描述

2 回答

?
慕村225694

TA貢獻1880條經驗 獲得超4個贊

通過將解碼調用和錯誤處理移至可重用函數來最大程度地減少代碼重復:


// Decode returns true if the request body is successfully decoded

// to the value pointed to by pv. Otherwise, decode writes an error

// response and returns false.

func decode(rw http.ResponseWriter, r *http.Request, pv interface{}) bool {

    err := json.NewDecoder(r.Body).Decode(pv)

    if err == nil {

        return true

    }

    rw.WriteHeader(http.StatusBadRequest)

    json.NewEncoder(rw).Encode(map[string]any{

        "status":  http.StatusBadRequest,

        "message": "error",

        "data":    map[string]any{"error": err.Error()},

    })

    return false

}

使用這樣的功能:


func userHandler(rw http.ResponseWriter, r *http.Request) {

    var u UserRequest

    if !decode(rw, r, &u) {

        return

    }

}


查看完整回答
反對 回復 2023-01-03
?
紅顏莎娜

TA貢獻1842條經驗 獲得超13個贊

最好抽象細節以提供有關您的處理程序所做工作的高級圖片。


func (h *rideHandler) handleCancelRideByPassenger(w http.ResponseWriter, r *http.Request) {


    ctx := r.Context()


    user := getUser(ctx)


    req := &cancelRequest{}


    if err := decode(r, req); err != nil {

        h.logger.Error("cancel ride: problem while decoding body request", zap.String("ip", r.RemoteAddr), zap.Error(err))

        h.respond.BadRequest(w, NewRESTError(reasonDecoding, "problem while decoding input parameters"))

        return

    }

    req.PublicID = chi.URLParam(r, "id")


    err := h.rideService.CancelRide(ctx, req, user)

    if err != nil {

        var validationErr *ValidationError

        switch {

        case errors.As(err, &validationErr):

            h.respond.BadRequest(w, NewRESTValidationError(reasonValidation, "problem while validating request", validationErr))

            return

        default:

            h.respond.InternalServerError(w, NewRESTError(reasonInternalError, "unknown problem occurred"))

            return

        }

    }


    h.respond.Ok(w, NewRESTResponse(&cancelRideResponse{Success: true}))


}

處理程序利用一些方便的糖函數來刪除重復,并提供處理程序的高級概述而不是底層細節。


func decode(request *http.Request, val interface{}) error {

    dec := json.NewDecoder(request.Body)

    dec.DisallowUnknownFields()

    return dec.Decode(val)

}


type Responder struct {

    Encoder Encoder

    Before BeforeFunc

    After AfterFunc

    OnError OnErrorFunc

}


func (r *Responder) writeResponse(w http.ResponseWriter, v interface{}, status int) {


    if r.Before != nil {

        status, v = r.Before(w, v, status)

    }


    encoder := JSON

    if r.Encoder != nil {

        encoder = r.Encoder

    }


    w.Header().Set("Content-Type", encoder.ContentType())

    w.WriteHeader(status)

    if err := encoder.Encode(w, v); err != nil {

        if r.OnError != nil {

            r.OnError(err)

        }

    }


    if r.After != nil {

        r.After(v, status)

    }


}


func (r *Responder) Ok(w http.ResponseWriter, v interface{}) {

    r.writeResponse(w, v, http.StatusOK)

}

可能您應該編寫自己的響應包或檢查開源中的可用內容。然后你就可以在任何地方使用這個具有相同響應結構的響應包。


查看完整回答
反對 回復 2023-01-03
  • 2 回答
  • 0 關注
  • 88 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號