How to Return JSON Data as HTTP Response in Golang Server

Robin
Updated on December 4, 2023

We often return JSON data from a Golang route we want to use as an API. Golang provides the encoding/json package to encode your data into JSON format.

There are 3 steps to return a JSON response from a Go server:

Step 1: Convert data into JSON format using the json.Marshal() method.

          jsonResponse, err := json.Marshal(response)
        

Step 2: Set the Content-Type header to application/json in the route.

          w.Header().Set("Content-Type", "application/json")
        

Step 3: Write the JSON response to the response writer

          w.Write(jsonResponse)
        

You can use a struct or a map to represent the data you want to return as JSON from your route.

I will give you examples with a struct and a map so that you choose either of them.

Return JSON Response From a Struct in Golang

I have/api/user route in my Golang server that is returning a JSON response. Here, I am using a struct to store the data I want to return.

The Person struct has 3 properties: Name, Age and Email.

You can also define the metadata for the JSON encoding process. It specifies the property names of your JSON data when you convert your struct into JSON format.

          package main

import (
	"encoding/json"
	"fmt"
	"net/http"
)

type Person struct {
	Name  string `json:"name"`
	Age   int    `json:"age"`
	Email string `json:"email"`
}

func userHandler(w http.ResponseWriter, r *http.Request) {
	person := Person{
		Name:  "John Doe",
		Age:   28,
		Email: "john.doe@gmail.com",
	}
	
	// Encode the response as JSON
	jsonData, err := json.Marshal(person)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
		
	// Set the Content-Type header to application/json
	w.Header().Set("Content-Type", "application/json")
	
	// Write the JSON response to the response writer
	w.Write(jsonData)
}

func main() {
	http.HandleFunc("/api/user", userHandler)
	
	fmt.Println("Server started on port 8000");
	http.ListenAndServe(":8000", nil)
}

        

Get request to the /api/user route will return the following output:

          {"age":28,"email":"john.doe@gmail.com","name":"John Doe"}
        

Inside my route handler function, I am creating a person object from the Person{} struct type.

Now call json.Marshal() method and pass the person object to convert it into JSON format. It will return 2 things: the JSON data and error (if there is any).

You can check for any potential error and handle it using the if statement.

Next, you have to set the HTTP response header for your route by calling the Header() method from the ResponseWriter instance.

For JSON response, set the Content-Type header to application/json to indicate that the response is in JSON format.

Finally, write your JSON data to the http.ResponseWriter by calling the Write() method.


Return JSON Response From a Map in Golang

Returning a JSON response from a map follows the same steps we used for a struct in the previous section.

The only difference is that we will use a map type to represent our data instead of a struct.

          package main

import (
	"encoding/json"
	"fmt"
	"net/http"
)

func userHandler(w http.ResponseWriter, r *http.Request) {
	person := map[string]interface{}{
		"Name":  "John Doe",
		"Age":   30,
		"Email": "john.doe@example.com",
	}

	// Encode the response as JSON
	jsonData, err := json.Marshal(person)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
		
	// Set the Content-Type header to application/json
	w.Header().Set("Content-Type", "application/json")
	
	// Write the JSON response to the response writer
	w.Write(jsonData)
}

func main() {
	http.HandleFunc("/api/user", userHandler)
	
	fmt.Println("Server started on port 8000");
	http.ListenAndServe(":8000", nil)
}

        

Get request to the /api/user route will return the following output:

          {"Age":28,"Email":"john.doe@gmail.com","Name":"John Doe"}
        

I have a person map that contains 3 properties: name, age, and email.

You can't provide any metadata for the JSON encoding process. Golang will use the same property names you used in the map as the property names for the converted JSON data.

When you pass the person map to the json.Marshal() method, it will convert the map into JSON format.

Now you can set the Content-Type header to application/json and write the JSON data to your response body.

Related Posts