programming

01 Introduction Golang Web Server

Web Introduction

The web is a collection of information available on a computer that is connected directly via the internet. This website contains information in any form such as text, audio, video and others. The web runs on an application called a web server, which is an application used to store and convey the contents of web information.

The web is a client and server based application. In simple terms, a client server is an application architecture concept that connects two parties. This client and server system will communicate with each other via a computer network or the internet. The client is tasked with sending requests to the server, while the server application is tasked with receiving requests from clients, processing data and returning the results of data processing to the client.

The advantage of this client and server architecture is that when we have changes to the application, only the server will change without having to make changes to the client, it can also be used and accessed by many clients at the same time, and can be accessed anywhere as long as it is connected to one network with the server.

Examples of web applications that act as clients are web browsers such as Chrome, Firefox, Opera, Edge and others. Meanwhile, the application that acts as a client is a Web Server, which contains the program code that we have created.

Golang Web

Golang is a popular language for creating the Web, especially Web APIs (backend). Apart from that, Golang also provides packages for Web needs and even includes packages to implement unit testing for the Web. So creating a website using Golang is easier because all the library packages needed are available without the need to add a framework.

How GolangWeb Works

  • Web Browser will send an HTTP request to the Web Server
  • Golang will receive the HTTP request and then execute the request as requested.
  • Golang will return data and render according to the client’s needs when the execution process is complete, for example it will return HTML, CSS, Javascript and others.
  • Golang will return the rendered content as an HTTP Response into the Web Browser.
  • The Web Browser will receive content from the Web Server and translate the content according to the content type.

Using Package net/http

In other programming, usually to create a web additional libraries or frameworks are needed. Meanwhile, in Golang there is no need to add any packages because a package called net/http is provided. Although actually there are several additional Golang frameworks that are widely recommended for the needs of creating this website.

Server Struct

Server is a struct contained in the net/http package which is used as a Web Server representation in Golang. There are several things we need to determine, such as the host and also the port where we will run the website. After creating the server, we can run the server using the ListenAndServe() function.

server := http.Server{
    Addr: "localhost:8080",
}

err := server.ListenAndServe()

OK, we will try to continue by creating a new project by creating the learning-golang-web folder and continuing to initialize the Golang module with the command below.

go mod init github.com/santekno/learn-golang-web

And after that we will create a main file with the name main.go with file contents like this.

package main

import "net/http"

func main() {
	server := http.Server{
		Addr: "localhost:8080",
	}

	err := server.ListenAndServe()
	if err != nil {
		panic(err)
	}
}

If we run this command terminal here

go build && ./learn-golang-web

So we can make sure our web server is running by looking at our browser with access

http://localhost:8080/

And a page not found will appear as below

web server golang

Added Handler

The server that we have created functions as a Web Server, while to receive HTTP Requests that enter the server we need a handler. The handler in Golang is represented in the interface where the contract contains a function called ServeHTTP() which is used as a function that we will later execute when we receive an HTTP Request.

One implementation of the Handler interface is HandlerFunc. We can use this to create an HTTP handler function. To get a better idea, let’s just try it by creating the function below.

func main() {
	var handlerTest http.HandlerFunc = func(w http.ResponseWriter, r *http.Request) {
		// logic web
		fmt.Fprint(w, "hello world")
	}

	server := http.Server{
		Addr:    "localhost:8080",
		Handler: handlerTest,
	}

	err := server.ListenAndServe()
	if err != nil {
		panic(err)
	}
}

We run the program and try to access by cURL like this

curl --location 'http://localhost:8080/'

And you will see the information on the terminal like this

➜  learn-golang-web git:(main) ✗ curl --location 'http://localhost:8080/'
hello world% 

Or you can access it directly in a browser and a hello world display will appear as well. This is a sign that we have created a handler by printing hello world on the web accessed by the client.

Using ServeMux

When we create a web server, of course we want to create lots of URL endpoints on one web server. HandleFunc unfortunately cannot support multiple endpoints, it can only output one endpoint URL. So another alternative that we need to implement from the handler is ServeMux. This is an implementation of Handler that can support multiple endpoints.

In the project that we have created, we will modify it by adding ServeMux so that we can create many endpoints in this one project.

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("/",func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w,"hello world")
	})

	mux.HandleFunc("/hi",func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w,"Hi")
	})

	server := http.Server{
		Addr:    "localhost:8080",
		Handler: mux,
	}

	err := server.ListenAndServe()
	if err != nil {
		panic(err)
	}
}

Now we have 2 endpoints which are:

  • http://localhost:8080/ : will return hello world data
  • http://localhost:8008/hi : will return Hi data

Get to know URL Patterns

The URL Pattern in ServeMux is very simple, so we just add the string we want to use as an endpoint without needing to enter our web domain. If the URL Pattern in ServeMux has been added at the end with a slash, it means that all URLs will receive a path with that prefix, for example, /images/ meaning it will be executed if the endpoint is /images/, images/example, /images/examples/again.

However, if our website has a longer URL pattern, the longer one will be prioritized, for example if we have URLs /images/ and /images/thumbnails then the first access will be prioritized to access images/thumbnails not /images .

Add Request

Request is a struct that represents an HTTP Request sent by a Web Browser. All request information is sent and we can retrieve data from the request such as URL, http method, http header, http body and others.

We try adding the main function under mux with the endpoint /hi, the addition is as below.

// read request
mux.HandleFunc("/req", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, r.Method)
    fmt.Fprintln(w, r.RequestURI)
})

We run the program and access the url /req which will print or display in the browser something like this

➜  learn-golang-web git:(main) ✗ curl --location 'http://localhost:8080/req'
GET
/req

In this handler we display the methods sent from the HTTP Request client and display the endpoint that is being accessed by the client.

comments powered by Disqus