慕村225694
通过将解码调用和错误处理移至可重用函数来最大程度地减少代码重复:// 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 }}
红颜莎娜
最好抽象细节以提供有关您的处理程序所做工作的高级图片。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)}可能您应该编写自己的响应包或检查开源中的可用内容。然后你就可以在任何地方使用这个具有相同响应结构的响应包。