From d7ccef3713946faafb5ab0af4f6fa7b071548d85 Mon Sep 17 00:00:00 2001 From: Maxime Delporte Date: Sun, 19 Oct 2025 11:34:42 +0200 Subject: [PATCH] Updating writeJSON helper method replacing json.Marshal() by json.MarshalIndent() method to improve responses readability. Updating README adding Performance sub-section. --- README.md | 9 ++++++++- cmd/api/helpers.go | 7 +++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 764b5d8..8ba2b66 100644 --- a/README.md +++ b/README.md @@ -71,4 +71,11 @@ A few other important things to mention : - Encoding of nested objects is supported. So, for example, if you have a slice of structs in Go that will encode to an *array of objects* in JSON. - Channels, functions and **complex** number types cannot be encoded. If you try to do so, you'll get a **json.UnsupportedTypeError** error at runtime. -- Any pointer values will encode as *the value pointed to*. \ No newline at end of file +- Any pointer values will encode as *the value pointed to*. + +### Performance + +json.MarshalIndent() takes 65% longer to run and uses around 30% more memory than json.Marshal(), as well as making two more heap allocations. Those figures will change depending on what you're encoding, but they're fairly indicative of the performance impact. + +For most applications this performance difference simply isn't something that you need to worry about. In real terms, we're talking about a few thousandths of a millisecond - and the improved readability of responses is probably worth this trade-off. +But if your API is operating in a very resource-constrained environment, or needs to manage extremely high levels of traffic, then this is worth being aware of and you may prefer to stick with using json.Marshal() instead. \ No newline at end of file diff --git a/cmd/api/helpers.go b/cmd/api/helpers.go index 9f310a4..3bd1458 100644 --- a/cmd/api/helpers.go +++ b/cmd/api/helpers.go @@ -49,8 +49,11 @@ http.ResponseWriter, the HTTP status code to send, the data to encode to JSON, 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) + /* + Use the json.MarshalIndent() function so that whitespace is added to + the encoded JSON. Here we use no line prefix ("") and tab indents ("\t") for each element. + */ + js, err := json.MarshalIndent(data, "", "\t") if err != nil { return err }