diff --git a/cmd/api/handlers.go b/cmd/api/handlers.go index fa1994d..3efd5de 100644 --- a/cmd/api/handlers.go +++ b/cmd/api/handlers.go @@ -31,7 +31,31 @@ func (app *application) getMovieHandler(w http.ResponseWriter, r *http.Request) } func (app *application) healthCheckHandler(w http.ResponseWriter, r *http.Request) { - fmt.Fprintln(w, "status: available!") - fmt.Fprintf(w, "environment: %s\n", app.config.env) - fmt.Fprintf(w, "version: %s\n", Version) + // JSON has to be double quoted. FYI you would never really do this + // js := `{"status": "available", "environment": %q, "version": %q}` + // js = fmt.Sprintf(js, app.config.env, Version) + // w.Write([]byte(js)) + data := map[string]string{ + "status": "available", + "environment": app.config.env, + "version": Version, + } + + // js, err := json.Marshal(data) + // if err != nil { + // app.logger.Error(err.Error()) + // http.Error(w, "The server encountered a problem and could not process your request", http.StatusInternalServerError) + // return + // } + // // 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') + // w.Header().Set("Content-Type", "application/json") + // w.Write(js) + err := app.writeJSON(w, 200, 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) + return + } } diff --git a/cmd/api/handlers_test.go b/cmd/api/handlers_test.go index 2d6ec20..3983dca 100644 --- a/cmd/api/handlers_test.go +++ b/cmd/api/handlers_test.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "encoding/json" "fmt" "io" "log/slog" @@ -36,12 +37,12 @@ func TestHealthRoute(t *testing.T) { } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) - assert.NilError(t, err) + jsonContent := make(map[string]string) - body = bytes.TrimSpace(body) + json.Unmarshal(body, &jsonContent) - assert.StringContains(t, string(body), "environment: test") + assert.Equal(t, jsonContent["environment"], "test") } func TestCreateMovieHandler(t *testing.T) { diff --git a/cmd/api/helpers.go b/cmd/api/helpers.go new file mode 100644 index 0000000..b1e7b4a --- /dev/null +++ b/cmd/api/helpers.go @@ -0,0 +1,33 @@ +package main + +import ( + "encoding/json" + "net/http" +) + +func (app *application) writeJSON(w http.ResponseWriter, status int, data any, headers http.Header) error { + + js, err := json.Marshal(data) + if err != nil { + return err + } + + 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 + } + + // Add 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 +}