diff --git a/cmd/api/healthcheck.go b/cmd/api/healthcheck.go index ef66e32..418ed8f 100644 --- a/cmd/api/healthcheck.go +++ b/cmd/api/healthcheck.go @@ -1,7 +1,6 @@ package main import ( - "encoding/json" "net/http" ) @@ -20,25 +19,9 @@ func (app *application) healthcheckHandler(w http.ResponseWriter, r *http.Reques "version": version, } - /* - Pass the map to the json.Marshal() function. This returns a []byte slice - containing the encoded JSON. If there was an error, we log it and send the client - a generic error message. - */ - js, err := json.Marshal(data) + err := app.writeJSON(w, http.StatusOK, data, nil) if err != nil { app.logger.Error(err.Error()) - http.Error(w, "The server encountered a problem and could not process your request.", http.StatusInternalServerError) + http.Error(w, "The server encountered a problem and could not process your request", http.StatusInternalServerError) } - - // Append a newline to the JSON. This is just a small nicety to make it easier to - // view in terminal applications. - js = append(js, '\n') - - // At this point, we know that encoding the data worked without any problem, so we - // can safely set any necessary HTTP headers for a successful response. - w.Header().Set("Content-Type", "application/json") - - // Use w.Write() to send the []byte slice containing the JSON as the response body. - w.Write(js) } diff --git a/cmd/api/helpers.go b/cmd/api/helpers.go index e92feeb..9f310a4 100644 --- a/cmd/api/helpers.go +++ b/cmd/api/helpers.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "errors" "github.com/julienschmidt/httprouter" "net/http" @@ -41,3 +42,38 @@ func (app *application) readIDParam(r *http.Request) (int64, error) { return id, nil } + +/* +Define a writeJSON() helper for sending responses. This takes the destination +http.ResponseWriter, the HTTP status code to send, the data to encode to JSON, and a +header map containing any additional HTTP headers we want to include in the response. +*/ +func (app *application) writeJSON(w http.ResponseWriter, status int, data any, headers http.Header) error { + // Encode the data to JSON, returning the error if there was one. + js, err := json.Marshal(data) + if err != nil { + return err + } + + // Append a newline to make it easier to view in terminal applications. + js = append(js, '\n') + + /* + At this point, we know that we won't encounter any more errors before writing the + response, so it's safe to add any headers that we want to include. We loop + through the header map and add each header to the http.ResponseWriter header map. + Note that it's OK if the provided header map is nil. Go doesn't throw an error + if you try to range over (or generally, read from) a nil map. + */ + for key, value := range headers { + w.Header()[key] = value + } + + // And the "Content-Type: application/json" header, then write the status code and + // JSON response. + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(status) + w.Write(js) + + return nil +}