Copper
  • Intro to Copper
  • Getting Started
    • Installation
    • Create Project
      • Go Templates
      • Tailwind
      • React
      • React + Tailwind
      • REST API
  • Guides
    • HackerNews Clone
    • Deploy with Fly.io
  • The Basics
    • Directory Structure
    • Dependency Injection
  • Core
    • App Lifecycle
    • Configuration
    • Error Handling
    • Logging
  • HTTP
    • Routing
    • Read & Write JSON
    • HTML Views
    • Middleware
  • SQL
    • Queries
    • Migrations
Powered by GitBook
On this page

Was this helpful?

  1. HTTP

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,
        },
    })
}
PreviousRoutingNextHTML Views

Last updated 2 years ago

Was this helpful?