Description

An IndentJSON engine configuration property would make it easier to configure JSON indentation across all request handlers in a project that produce JSON.

Background

In production, it often makes sense for request handlers to respond with minified JSON response using (Content) JSON(code, obj) for performance. However, during development IndentedJSON() is nice for debugging. I've accomplished this by wrapping JSON()/IndentedJSON() in a helper function like this:

// Render a JSON response with the given status code. If debugging
// is enabled, render a pretty-printed JSON response.
func json(c *gin.Context, code int, obj any) {
    if gin.IsDebugging() {
        c.IndentedJSON(code, obj)
    } else {
        c.JSON(code, obj)
    }
}
// DELETE /sim/:sid/asset/:aid
func removeSimAsset(c *gin.Context, e *engine.Engine) {
    simId := c.Param("sid")
    assetId := c.Param("aid")

    sim, ok := e.Simulation(simId)
    if !ok {
        json(c, http.StatusNotFound, gin.H{"error": "simulation not found"})
        return
    }

    asset, ok := sim.DeleteAsset(assetId)
    if !ok {
        json(c, http.StatusNotFound, gin.H{"error": "asset not found"})
        return
    }

    json(c, http.StatusOK, asset)
}

This is a bit of an ugly hack. In larger projects with hundreds of request handlers, configuring them all to use json() can be challenging to maintain.

Introducing an engine configuration to produce indented JSON would make this easier and cleaner.

    router := gin.New()
    router.IndentJSON = true

Final Thoughts

I think it would be good to talk about making this a bit more generic.

Gin has fantastic support for different content types (JSON, XML, TOML, etc). Each content type has it's own renderer, wrapped by a Context function (JSON(), XML(), YAML(), etc.). IndentedJSON() is a bit of an odd one; it's the only one that is a pretty-printed variant of another content type.

When IndentedJSON() was implemented back in https://github.com/gin-gonic/gin/commit/abcc6d9dec17b1fd66f07aa2a0202eda8954dd39 I think it would have been a good idea to talk about the other content types. XML can be pretty printed or minified, and so can HTML. Personally, I would have preferred to add an engine configuration for indented/pretty-printed responses rather than create functions for each variant.

    router := gin.New()
    router.PrettyFormatResponse = true

Any thoughts? Now that IndentedJSON() has been around for a while, it doesn't make sense to remove it any time soon. Just something to think about :-)

Environment

  • go version: 1.19
  • gin version (or commit ref):1.9.1
  • operating system: Linux md2qhqqc 5.10.0-23-amd64 #1 SMP Debian 5.10.179-1 (2023-05-12) x86_64 GNU/Linux