Read & Write JSON

Copper provides chttp.ReaderWriter that can be used to read, validate, and respond in JSON format. chttp.ReaderWriter is available by default on Routers generated by the Copper CLI.

Read JSON

In the example below, JSON is read from the request body into the body variable using the ReadJSON method. On failure, it writes an appropriate status code & response to the response body and returns false.

func (ro *Router) HandleRocketLaunch(w http.ResponseWriter, r *http.Request) {
    var body struct {
        RocketID string `json:"rocket_id"`
    }
    
    if ok := ro.rw.ReadJSON(w, r, &body); !ok {
        return
    }
    
    // Handle request with body..
}

Validate Request Body

The ReadJSON method integrates with asaskevich/govalidator to validate the request body. If the validation fails, the method responds with 400 Bad Request status code.

var body struct {
    RocketID string `json:"rocket_id" valid:"required`
}

Write JSON

The WriteJSON method handles marshaling, error checking, and setting the Content-Type: application/json header.

Below is a full example of reading a validated request body, calling the business logic layer, handling errors, and finally writing an HTTP response.

func (ro *Router) HandleRocketLaunch(w http.ResponseWriter, r *http.Request) {    
    var body struct {
        RocketID string `json:"rocket_id" valid:"required"`
    }
    
    if ok := ro.rw.ReadJSON(w, r, &body); !ok {
        return
    }
    
    launchID, err := ro.rockets.Launch(r.Context(), body.RocketID)
    if err != nil {
        ro.logger.Error("Failed to launch rocket", err)
        w.WriteHeader(http.StatusInternalServerError)
        return
    }

    ro.rw.WriteJSON(w, chttp.WriteJSONParams{
        StatusCode: http.StatusCreated,
        Data: map[string]string{
            "launch_id": launchID,
        },
    })
}

Last updated