Build Server With Go Under 10 minutes
Tags: webdev, beginners, tutorial, go
Published: 2023-01-23 17:03:43

The introduction of microservice architecture revolutionised the way softwares are developed today. Post microservice architecture replaced monoliths, containers replaced virtual machines. With this transformations, almost every modern software is built in microservice architecture. Golang is widely used among developers building Microservices. Its usage can be seen across industries as a popular option for server-side application development. 

![Go Starter](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nzff2y2jg0aqgqak3vnx.png)

Go is a great language for creating simple yet efficient web servers and web services. It provides a built-in HTTP package that contains utilities for quickly creating a web or file server.

## Why Build backend Server with Go? 🗽
The Story goes, Go was allegedly created by Google engineers while they waited for other programmes to compile. They had to completely rethink system development as a result of their displeasure with their toolset, which drove them to develop a lean, mean, and compiled solution that supports huge multithreading, concurrency, and performance under stress.


> Every organisation looking at scale is leveraging Golang to build containerised microservices 

Several programming languages have less memory and cannot communicate with the hardware. Thus, developers mostly prefer Golang that helps build software. Besides, it is the procedural language that is beneficial for implementing reliable, effective, and simple software. Golang supports the environment to accept different patterns that are equivalent to other more beneficial languages. Tech gaints have started using Go, post it's inception. 


![Companies using Golang](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a5h4meb39jl4cna4njnu.png)

<figcaption>Graphics: Bacancy Techology</figcaption>


It can be a genuine delight to run Go on contemporary hardware, either inside containers or on virtual machines. Go was created to allow concurrency and scale as more cores are added since it was intended to run on multiple cores. If you are someone who is interested in the Cloud Native Ecosystem, Go is the language you should start with. 

## What we will build? 👨‍🚒
The following tutorial will include building a basic backend server with just `main.go` file. I won't be making the application complex by following the directory structure. Connecting DBs would make the tutorial a bit large and might confuse beginners who are just starting out with Go. 

In the application we will learn how to add multiple routes, start server, write controllers and perform GET and POST requests. 

![System Design for Server](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wk9yekizgjbno819dvq4.png)

The schematic diagram above is an attempt to showcase how the server is to be designed to work. The server we will be building will have 2 routes one for GET and the other for POST. Where in the home route will be configured for GET and the form route for POST.  

## Pre-Requisite ⚙️
If you don't have Go installed in your system follow the [official docs](https://go.dev/doc/install) to install it. Trust me it won't take more than 3 minutes to do it. To check if you have installed it properly, just run:

```go
go version
```
When I run the particular command, I get `go version go1.17 darwin/amd64` in return. If you get something similar **congratulations 🎉** you are all set to begin your backend developer journey with Go. 

## Understanding: Syntax 👨‍🏫
Go is syntactically similar to C, but with memory safety, garbage collection, structural typing, and CSP-style concurrency. Now, if you have never coded in Golang before and don't have any clue how the syntax works. Refer to Namaste-Go. A learning repository, to get started with Go lang. 

{% github Aniket762/namaste-go%}

Once, you are done with the basics let's dive into building the backend server with Go lang. 

## Developing the Backend 👨‍💻
Let's create a directory `goServer` and change our current directory to it. 

```shell
mkdir goServer && cd goServer
```
Post running the command we are in the `goServer` directory, all you need to do now, create a `main.go` which you can name according to whatever naming convention you follow, say `server.go`. As mentioned before, we won't be following the modularised approach to keep things simple. So, let's create the file.

```shell
touch main.go
```
Running the command, creates an empty file in our working directory over here which is goServer.

We need to define a package for the Go file. Since this will be the main file we have, we add the package main.
```go
package main
```
The above line is the first line of the program.


### Importing Packages 🛍️
Now, let's import all the necessary packages we require to build our application.

```go
import (
	"fmt"
	"log"
	"net/http"

	"github.com/gorilla/mux"
)
```
Now, let us understand why did we include so many packages into our application. Demystifying the packages:

1️⃣ fmt: for printing message
2️⃣ log: for logging errors
3️⃣ net/http: for handling HTTP requesting when creating GO APIs
4️⃣ gorilla/mux: for URL matcher and routing. It helps in implementing request routers and match each incoming request with its matching handler.

If, I would have been you and read all the imports, I would have been pretty much confused. But, trust me once you read the blog I can bet you would get a clear idea why we included the following packages. 

Creating the `go.mod` file which will store all the necessary packages required, it is similar to package.json. 

```go
go mod init github.com/Aniket762/namaste-go/goServer
```
To ensure that the go.mod file matches the source code in the module, we run
```go
go mod tidy
```
All the imported packages except for one is already present with the binary file you executed while installing Go. So, let's install `Gorilla Mux`.

```go
go get "github.com/gorilla/mux"
```
If you are a JavaScript developer, the following command is pretty much similar to `npm install <package_name>`


Lastly, before we run the program to check if everything is in sync till now. We add the `main()` function which would get first executed when we compile the program. 

```go
func main() {
    fmt.Printf("Hello from GoServer 👋")
}
```

Summarising the entire codebase till now,
```go 
package main

import (
	"fmt"
	"log"
	"net/http"


	"github.com/gorilla/mux"
)

func main(){
	fmt.Printf("Hello from GoServer 👋")
}
```

To run the following Go Script execute the following command.
```go 
go run main.go
```
If you get `Hello from GoServer 👋` in the console. Wohoo! You are all set to proceed further!

### Building the server 💪
First creating a new request router. The router is the main router for our web application and will later be passed as parameter to the server. It will receive all HTTP connections and pass it on to the request handlers we will register on it. We create the router, in the main function.

```go
r := mux.NewRouter()
```
Post registering the router, let's define the endpoints using HandleFunction. We call HandleFunction by r.HandleFunc(...)
```go
   r.HandleFunc("/",greetingsHandler).Methods("GET")
   r.HandleFunc("/form",formHandler).Methods("POST")
```
In HandleFunc we provide 2 parameters, firstly the route in which we want to see the magic and secondly we write the name of the particular controller function which performs the magic. The corresponding GET and POST has the regular meaning, to build the CRUD operation for the application just add PUT and DELETE according to the route. 

### Writing the GET Route
Now, as we have defined the routes, let us write the controllers. Starting out with the greetingsHandler aka GET Controller.
```go
func greetingsHandler(w http.ResponseWriter, r *http.Request){
	fmt.Fprintf(w,"Greeting from Go Server 👋")
}
```
By default, this function accepts a ResponseWriter to send a response back and a Request object that sends the parameters to the server. The controller simply sends back a message. 

To check if our GET function is working, let's write the code to spin up the server in the main function.  
```go
        fmt.Printf("Starting server at port 8000\n")
	log.Fatal(http.ListenAndServe(":8000",r))
``` 
The Listen and Serve function keep the custom port open, here 8000. Until and unless the program is interrupted the server is up. 

Before we move forward with the POST request handler let us, check if everything is functioning as expected. Let's comment out the POST route and go for it. Your code should look something like this 👇
```go
package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/gorilla/mux"
)

func greetingsHandler(w http.ResponseWriter,r *http.Request){
	fmt.Fprintf(w,"Greeting from Go Server 👋")
}


func main(){
	r := mux.NewRouter()
	
	r.HandleFunc("/",greetingsHandler).Methods("GET")
	
	fmt.Println("Hello from GoServer 👋")
	fmt.Printf("Starting server at port 8000\n")
	log.Fatal(http.ListenAndServe(":8000",r))
}
```
### Running the server 🏃‍♂️
Now, we have the basic server ready. Let us create a build and then run it.

Using the particular command we generate the .exe file if we are on windows and .deb if in linux. Ultimately generating a binary file which can be executed. 
```go 
go build
```
Post creating the binary file, we execute the file via the following command.
```go 
go run main.go
```
Hit, `localhost:8000` in your favourite browser. If it is something like this as shown below. Cheer yourself up, you have completed 80% of the tutorial.

![Get Request UI](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hls9vhj0jzek874nofyl.png)

### Leveling Up: Post Request 🚀
It's great to see you are still reading. The beauty of Go can be enjoyed when you start with Post Requests. We will be using json encoding so, let's import another module for it,
```go
import(
   "encoding/json"
)
```
First let's create a simple struct `Founder`, which will consists name, age, email address and name of the company they have founded. 
```go
type Founder struct{
	Name string `json:"name"`
	Age uint32 `json:"age"`
	Email string `json:"email"`
	Company string `json:"company"`
}
```
If you are a JavaScript developer struct is similar to ES6 class. Now, let us define a slice, which is similar to vectors in C++. 
```go
var founders []Founder
```
A slice is similar to an array, the difference is that when you want to use arrays in Golang you need to define the length. This is why we use a slice, we also tell it that it will contain posts. Over here founders is a slice of type Founder. 

Let us insert dummy data into our slice, such that when we return our slice after perform POST request we can visualise more than element in our slice.

```go
founders = append(founders, Founder{Name:"Mehul",Age:23,Email:"random@random.com",Company: "BharatX"})
``` 

Let us write the script for POST Request Handler aka form Handler one step at a time.

```go
func formHandler(w http.ResponseWriter, r *http.Request){
     w.Header().Set("Content-Type","application/json")
}
```
We define the the Header for the particular controller over here. We’re just setting the header “Content-Type” to “application/json”. 

```go 
func formHandler(w http.ResponseWriter, r *http.Request){
	w.Header().Set("Content-Type","application/json")
	
	var founder Founder
	json.NewDecoder(r.Body).Decode(&founder)
}
```
We send parameters while sending the request, as key value pairs. The request object is broken down into string with decoder method. Let's try to play a bit around with the parameter we have received.
```go
func formHandler(w http.ResponseWriter, r *http.Request){
	w.Header().Set("Content-Type","application/json")
	
	var founder Founder
	json.NewDecoder(r.Body).Decode(&founder)

	founder.Age = founder.Age * 2;
	founders = append(founders,founder)
	
	json.NewEncoder(w).Encode(founders)
}
```

We multiple the age of the founder by two, and append it to the slice. Then we use the encoding package to encode all the founders data as well as returning it at the same line. Ultimately, sending in the POST request, modifying the data, appending into the slice and then returning back the slice. 

So, your final piece of code should look like:
```go
package main

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

	"github.com/gorilla/mux"
)

type Founder struct{
	Name string `json:"title"`
	Age uint32 `json:"age"`
	Email string `json:"email"`
	Company string `json:"company"`
}

var founders []Founder

func greetingsHandler(w http.ResponseWriter,r *http.Request){
	fmt.Fprintf(w,"Greeting from Go Server 👋")
}

func formHandler(w http.ResponseWriter, r *http.Request){
	w.Header().Set("Content-Type","application/json")
	
	var founder Founder
	json.NewDecoder(r.Body).Decode(&founder)

	founder.Age = founder.Age * 2;
	founders = append(founders,founder)
	
	json.NewEncoder(w).Encode(founders)
}

func main(){
	r := mux.NewRouter()

	founders = append(founders, Founder{Name:"Mehul",Age:23,Email:"random@random.com",Company: "BharatX"})

	r.HandleFunc("/",greetingsHandler).Methods("GET")
	r.HandleFunc("/form",formHandler).Methods("POST")

	fmt.Println("Hello from GoServer 👋")
	fmt.Print("Starting server at port 8000\n")
	log.Fatal(http.ListenAndServe(":8000",r))
}
``` 

The process does not end here, let us check on what we have developed so far is working or not. Firstly, let's build and spin up the server
```go
go build && go run main.go
```
### API testing with Postman 📬
Now, let's head over to Postman. You can use anything you want to but I prefer Postman. 
![Postman setup for API testing](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q2gn0u4jn0cso0zzscq7.png)
Firstly, put the API endpoint in this case it is, `http://localhost:8000/form`, select POST from the dropdown. Navigate to Body tab and choose raw and then select JSON. Write dummy data, here is the one I wrote:
```json
{
    "name":"Kunal Shah",
    "age":42,
    "email":"kunal@coolguy.com",
    "company":"CRED"
}
```
Hit the Send button. Check for the status code and the output which you got. Incase it's exactly what you were expecting, then **it's time for celebration** 🍻🥳

## Outro 💚
Firstly, thanks a lot if you are still reading. Remember, Go is like chess or, well, the game of Go: it takes a moment to learn and a lifetime to master. Luckily, unlike chess, Go’s difficulty goes down with experience and soon you’ll be coding fast and furious programs in one of the world’s most modern languages. 

The purpose of this blog was to give programmers who are enthusiastic about backend development with Golang a kickstart. The server built consists of basic features such as multiple routes, creation of GET and POST request, building binaries, running server and ultimately giving a basic understanding on how exactly Go works.

I plan to write more backend development with Go tutorials. If you don't want to miss out, follow me at [Twitter](https://twitter.com/itzaniket762). Till then checkout the wonderfully curated [Go Documentation](https://go.dev/doc/). Incase, you have some questions regarding the article or want to discuss something under the sun feel free to connect with me on LinkedIn 💖

> If you run an organisation and want me to write or create video tutorials please do connect with me 🤝