Web Server Creation with Go net/http package

Cihan Ozhan

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 birleştirme işlemi
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 modelsfolder.

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

Resource: http://www.cihanozhan.com/web-server-creation-with-golang-net-http-package/

Good luck!
Cihan Özhan

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade