in Go

Web Server Creation with Go net/http package

Web Server Creation with Go net/http package

One of the reasons we use the Go programming language is undoubtedly high performance and fast programming capabilities.

In this article, we will develop a few example projects about Go web servers. These examples’ll start with simple uses. We will further improve these examples step by step.

The Go programming language has a good package to develop high-performance web applications. This package name is “net/http”

To read the package documentation: https://golang.org/pkg/net/http/

Example 1:

In our first example, we will create a web server  as simple as possible. This server will broadcast over localhost:9000. And then we will simply look at the use of the parameter via URI.

Let’s run the code below:

package main
 
import (
    "fmt"
    "net/http"
)
 
func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Merhaba %s", r.URL.Path[1:])
}
 
func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":9000", nil)
 
    fmt.Println("Web Server")
}

How does this practice basically work?

First, the main() method has two basic codes. One of them is http.HandleFunc() and the other is ListenAndServer(). http.HandleFunc() must have an handler object. This is why, we used the handler() function above. When handler() is executed, it takes a pointer to the ResponseWriter and the incoming Request as parameters.  We can obtain many http-related data from the incoming HTTP request. 

In this example, we only get URI. Then we do an interrupt on this URI to get the next URI data from the first element. So we’ll just have that part of URI URI: www.xyz.com/abc 

Example 2:

Now, we can develop our second application

This output of this application will be the same as the output of the first application.

Example 3:

In this example, we will use Go template structure. First, we need to have a HTML template, and then we will include this HTML page in the application. 

Application folder structure:

  • page.html
  • webServer.go

First, we will create our HTML page:

Now, we can write Go codes for our application:

package main
 
import (
    "fmt"
    "io/ioutil"
    "net/http"
)
 
func loadFile(fileName string) (string, error) {
    bytes, err := ioutil.ReadFile(fileName)
    if err != nil {
        return "", err
    }
    return string(bytes), nil
}
 
func handler(w http.ResponseWriter, r *http.Request) {
    var body, _ = loadFile("page.html")
    fmt.Fprintf(w, body)
}
 
func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":9000", nil)
}

The output of this application will be the same as the output of the first application.

Example 4:

In this application, we will apply Go’s template model. But this time we will also use the placeholder properties of Go in the template.

Application folder structure:

  • page.html
  • webServer.go

Now, we can write our Go codes for our application:

The Go codes for this application are as follows:

package main
 
import (
    "bytes"
    "html/template"
    "io/ioutil"
    "net/http"
)
 
type Page struct {
    Title           string
    Author          string
    Header          string
    PageDescription string
    Content         string
    URI             string
}
 
func loadFile(fileName string) (string, error) {
    bytes, err := ioutil.ReadFile(fileName)
    if err != nil {
        return "", err
    }
    return string(bytes), nil
}
 
func handler(w http.ResponseWriter, r *http.Request) {
 
    // String merge operation
    var builder bytes.Buffer
    builder.WriteString("KodLab yayınevinden çıkardığımız Yazılımcılar İçin İleri Seviye T-SQL kitabımın özellikleri aşağıdaki gibidir;\n")
    builder.WriteString("704 Sayfa\n")
    builder.WriteString("ISBN: 9.786.055.201.142\n")
    builder.WriteString("Fiyat: 37 TL\n")
    builder.WriteString("Boyut: 15 x 21\n")
    builder.WriteString("2. Baskı\n")
 
    uri := "www.cihanozhan.com/yazilimcilar-icin-ileri-seviye-t-sql-programlama-kitabi/"
 
    page := Page{
        Title:           "Kitap : İleri Seviye T-SQL Programlama",
        Author:          "Cihan Özhan",
        Header:          "İleri Seviye T-SQL Programlama",
        PageDescription: "İleri Seviye T-SQL Programlama kitap tanıtım sayfası",
        Content:         builder.String(),
        URI:             "http://" + uri}
    t, _ := template.ParseFiles("page.html")
    t.Execute(w, page)
}
 
func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":9000", nil)
}

Example 5:

This application will be our last application for this article. This is why, we will develop a slightly more complicated application.

Application folder structure:

We can start by creating sample data for our application. For this we will create json files under the json folder.

users.json

[
    {
        "ID": 1,
        "Username": "CihanOzhan",
        "FirstName": "Cihan",
        "LastName": "Özhan",
        "Interest": "C#, GO, SQL Server, Oracle, Machine Learning, BigData",
        "Profile": "https://www.linkedin.com/in/cihanozhan"
    },
    {
        "ID": 2,
        "Username": "KerimFirat",
        "FirstName": "Kerim",
        "LastName": "Fırat",
        "Interest": "C, C++, Java, Linux, Android",
        "Profile": "https://www.linkedin.com/in/kerim-firat-0a3b6338"
    },
    {
        "ID": 3,
        "Username": "BarisOzhan",
        "FirstName": "Barış",
        "LastName": "Özhan",
        "Interest": "Web Tasarım, SEO, SEM",
        "Profile": "https://www.linkedin.com/in/barisozhan"
    }
]

interests.json

[
    {
        "ID": 1,
        "Name": "C#"
    },
    {
        "ID": 2,
        "Name": "GO"
    },
    {
        "ID": 3,
        "Name": "SQL Server"
    },
    {
        "ID": 4,
        "Name": "Oracle"
    },
    {
        "ID": 5,
        "Name": "BigData"
    },
    {
        "ID": 6,
        "Name": "Machine Learning"
    },
    {
        "ID": 7,
        "Name": "C"
    },
    {
        "ID": 8,
        "Name": "C++"
    },
    {
        "ID": 9,
        "Name": "Java"
    },
    {
        "ID": 10,
        "Name": "Linux"
    },
    {
        "ID": 11,
        "Name": "Android"
    },
    {
        "ID": 12,
        "Name": "Web Tasarım"
    },
    {
        "ID": 13,
        "Name": "SEO"
    },
    {
        "ID": 14,
        "Name": "SEM"
    }
]

userInterestMappings.json

[
    {
        "UserID": 1,
        "InterestID": 1
    },
    {
        "UserID": 1,
        "InterestID": 2
    },
    {
        "UserID": 1,
        "InterestID": 3
    },
    {
        "UserID": 1,
        "InterestID": 4
    },
    {
        "UserID": 1,
        "InterestID": 5
    },
    {
        "UserID": 1,
        "InterestID": 6
    },
    {
        "UserID": 2,
        "InterestID": 7
    },
    {
        "UserID": 2,
        "InterestID": 8
    },
    {
        "UserID": 2,
        "InterestID": 9
    },
    {
        "UserID": 2,
        "InterestID": 10
    },
    {
        "UserID": 2,
        "InterestID": 11
    },
    {
        "UserID": 3,
        "InterestID": 12
    },
    {
        "UserID": 3,
        "InterestID": 13
    },
    {
        "UserID": 3,
        "InterestID": 14
    }
]

Now, we will create a page.html page for our new application:

We’re almost ready! Now, to create our model files, we can go to our models folder.

Interest.go

package models
 
type Interest struct {
    ID   int
    Name string
}

InterestMapping.go

package models
 
type InterestMapping struct {
    UserID     int
    InterestID int
}

Page.go

package models
 
type Page struct {
    ID          int
    Name        string
    Description string
    URI         string
}

User.go

package models
 
type User struct {
    ID        int
    Username  string
    FirstName string
    LastName  string
    Profile   string
    Interests []Interest
}

UserViewModel.go

package models
 
type UserViewModel struct {
    Page  Page
    Users []User
}

We prepared the general structure of the application. Now, we will write the execution code of the application.

webServer.go

package main
 
import (
    "encoding/json"
    "html/template"
    "io/ioutil"
    "net/http"
 
    model "./models"
)
 
func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":9000", nil)
}
 
func handler(w http.ResponseWriter, r *http.Request) {
 
    page := model.Page{ID: 3, Name: "Kullanıcılar", Description: "Kullanıcı Listesi", URI: "/users"}
    users := loadUsers()
    interests := loadInterests()
    interestMappings := loadInterestMappings()
 
    var newUsers []model.User
 
    for _, user := range users {
 
        for _, interestMapping := range interestMappings {
            if user.ID == interestMapping.UserID {
                for _, interest := range interests {
                    if interestMapping.InterestID == interest.ID {
                        user.Interests = append(user.Interests, interest)
                    }
                }
            }
        }
        newUsers = append(newUsers, user)
    }
 
    viewModel := model.UserViewModel{Page: page, Users: newUsers}
 
    t, _ := template.ParseFiles("template/page.html")
    t.Execute(w, viewModel)
}
 
func loadFile(fileName string) (string, error) {
    bytes, err := ioutil.ReadFile(fileName)
    if err != nil {
        return "", err
    }
    return string(bytes), nil
}
 
func loadUsers() []model.User {
    bytes, _ := ioutil.ReadFile("json/users.json")
    var users []model.User
    json.Unmarshal(bytes, &users)
    return users
}
 
func loadInterests() []model.Interest {
    bytes, _ := ioutil.ReadFile("json/interests.json")
    var interests []model.Interest
    json.Unmarshal(bytes, &interests)
    return interests
}
 
func loadInterestMappings() []model.InterestMapping {
    bytes, _ := ioutil.ReadFile("json/userInterestMappings.json")
    var interestMappings []model.InterestMapping
    json.Unmarshal(bytes, &interestMappings)
    return interestMappings
}

When we run the application, we will finally get the following output:

Github: https://github.com/cihanozhan/golang-webapi-samples

Good luck!
Cihan Özhan

Write a Comment

Comment