In this blog post, I am going to talk about HTTP server and how to return different types of HTTP response(text, JSON, html) in Go.

Plain Text Response Link to heading

Creating a web server in Go is very simple and we can do it by writing just a few lines of code.We need to use net/http package to create an HTTP server. This is how a simple HTTP server code looks like in Go.

server.go

package main 
import ( 
         "fmt" 
         "net/http" 
       )
func main() { 
        http.HandleFunc("/", handler) 
        http.ListenAndServe(":8081", nil) 
} 
func handler(w http.ResponseWriter, r *http.Request) {                               
     fmt.Fprintf(w, "Hello World!") 
}

Once we run the file with command go run server.go, we will have a web server listening on port 8081. Open a browser and access http://localhost:8081/ you will get plain text response as Hello World!. Above web server is very simple and it will respond with Hello World! no matter what path you type after /.

JSON Response Link to heading

Most of the web services use JSON to communicate with clients and one web service can be used for different clients like Web Application, Android Application or iOS Application. Now, we will see how to return a JSON response in Go.

At first, I will create User struct which will store user information. We will use the same struct to return user information as JSON response. In your application, you might want to get data from some database or file and return it as a JSON response.

type User struct { 
     Id    int     `json:"id"` 
     Name  string  `json:"name"` 
     Email string  `json:"email"` 
     Phone string  `json:"phone"` 
}

Let’s create a handler name jsonHandler which will handle /json and return user information as JSON response.

To send JSON response, we need to encode the user information using JSON encoder and set the response header Content-Type to application/json while sending the response. This is how jsonHandler code should look like.

func jsonHandler(w http.ResponseWriter, r *http.Request) {     
      
      w.Header().Set("Content-Type", "application/json") 
      user := User {
                    Id: 1, 
                    Name: "John Doe", 
                    Email: "johndoe@gmail.com", 
                    Phone: "000099999"
               } 
      
     json.NewEncoder(w).Encode(user) 
}

Register the jsonHandler, run the file with go run server.go and access http://localhost:8081/json in browser, you should get a JSON response as below.

{ 
  "id": 1, 
  "name": "John Doe", 
  "email": "johndoe@gmail.com", 
  "phone": "000099999" 
}

HTML or Template as Response Link to heading

We will add a new handler templateHandler which will handle /template and respond with HTML file (template) as a response. Let’s create a template file as template.html which will display user information and will be used by templateHandler.

<html> 
   <head> 
   </head> 
   <body> 
     <h3>Name : {{.Name}}   </h3> 
     <h3>Email : {{.Email}} </h3> 
     <h3>Phone : {{.Phone}} </h3> 
   </body> 
</html>

New handler will use html/template package to parse and execute template files. Also, we need to set Content-Type header to text/html; charset=utf-8 otherwise template will be returned as plain text.

func templateHandler(w http.ResponseWriter, r *http.Request) { 
      w.Header().Set("Content-Type", "text/html; charset=utf-8") 
      
      t, err := template.ParseFiles("template.html") 
      if err != nil { 
             fmt.Fprintf(w, "Unable to load template") 
        } 
     
    user := User{
                  Id: 1, 
                  Name: "John Doe", 
                  Email: "johndoe@gmail.com", 
                  Phone: "000099999"
               } 
    
     t.Execute(w, user) 
}

After adding the new handler, the code should look as below.

server.go

package main

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

type User struct  {
	Id int 		 `json:"id"`
	Name string	 `json:"name"`
	Email string `json:"email"`
	Phone string `json:"phone"`
}

func main() {
	http.HandleFunc("/", handler)
	http.HandleFunc("/json", jsonHandler)
	http.HandleFunc("/template", templateHandler)
	http.ListenAndServe(":8081", nil)
}

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello World!")
} 

//jsonHandler returns http respone in JSON format.
func jsonHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	user := User{Id: 1, 
				Name: "John Doe", 
				Email: "johndoe@gmail.com", 
				Phone: "000099999"}
	json.NewEncoder(w).Encode(user)	
}

//templateHandler renders a template and returns as http response.
func templateHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	t, err := template.ParseFiles("template.html")
	if err != nil {
		fmt.Fprintf(w, "Unable to load template")
	}

	user := User{Id: 1, 
		Name: "John Doe", 
		Email: "johndoe@gmail.com", 
		Phone: "000099999"}
	t.Execute(w, user)
}

template.html

<html>
    <head>
    </head>
    <body>
        <h3>Name : {{.Name}}</h3>
        <h3>Email : {{.Email}}</h3>
        <h3>Phone : {{.Phone}}</h3>
    </body>
</html>

Once you run the file and access http://localhost:8081/template in the browser, you should be able to get user details rendered with the template.