# Golang for Frontend developers | Beginner guide to Golang

- Are you a beginner and you want to start Golang but don't know how?
- You have written `express.js` code and want to create micro-services using Golang? 

Then this article is for you. This article will guide you step by step building block to build a scalable Golang project but in simple words.

## Do I really need Golang? 
Before going further you should ask this question to yourself and your teammates. Hope you are not migrating just for the sake that you want to try out something new. Golang is a new language but it is not that new. The first stable release was in 2009 the same as nodejs. Due to similarity or say javascript popularity, Nodejs become famous in a few years. React, Angular and other frontend framework help to make nodejs one of the popular language in the market. 

Golang has a different type of fans. Just like any other stable language, it took time for Golang to become famous. Now it is a buzz word in all industries. However, Golang is not just a buzz word. It has defiantly the potential to become the first choice and it is happing already. Now Golang is the first choice for micro-service development. 

The biggest reason for adaptation, This language is maintained by Google Team. And companies like Netflix, Google, Facebook are using it in production [read more](https://github.com/golang/go/wiki/GoUsers). Tools like [Docker](https://www.docker.com/) and [kubernetes](https://kubernetes.io/) has been written on Golang. Due to its high performance, simplicity it is now goto go language. 

**You can ask me a question. If Golang is so good and it is in the market for such a long time why I am writing this blog now?**
The answer is simple, Recently one of my tool build on Golang went live in my Organization. So I want to share my experience.

## Prerequisite
- **Golang[v1.16 and above]:** You should have the latest version of Golang in your system. You can download and install Golang [here](https://golang.org/doc/install).
- Basic understanding of async programming
- Basic understanding of functional programming
- Linux/Unix: Since the examples and command will be written for the UNIX system. You can find similar command if you are working on a window system

### Verify Golang

To verify, open and type the below command 

```bash
go version

## output
go version go1.16.1 darwin/amd64
```

![golang-introduction-hello-world.jpeg](https://cdn.hashnode.com/res/hashnode/image/upload/v1617273449209/NCPiSaJOg.jpeg)

## Golang First program, "Hello, Golang ❤️"
Writing a Golang program is pretty simple. You can create a file with "package main".

```bash
touch main.go
```

Add below code in `main.go`

```go
package main

import "fmt"

func main() {
	fmt.Println("Hello, Golang ❤️")
}
```

Running a Golang program: `go run main.go`

**Explanation:** Every Go Executable program required an entry file which should be defined in package main. And file should contain a `main function`. 

**Note:** Golang is a compile and statically typed language, meaning you need to compile the program before running it. However, when you run an app using `go run` command. It creates a binary in the temp folder and executes it. In production, You should do this by own. You should not run an app using Go run.

#### Running app using the build command

```bash
## compile and build go app[You can give any name to executable using -o]
go build -o todo_app.exe main.go 

#### running a go app

./todo_app.exe
```

#### Clean up, Gitignore setup [optional]

```bash
## .gitignore

# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/
```


![manager.jpeg](https://cdn.hashnode.com/res/hashnode/image/upload/v1617273749533/HOT8MwfMU.jpeg)

## Golang package manager, Start a new project

In version 1.11, Go introduce a new package manager similar to nodejs npm. This makes it easier to start a new project. To start a new project, You can create a folder and follow the below command.

```bash
mkdir todo_app
cd todo_app
go mod init github.com/deepakshrma/todo_app
```

**Explanation:** Here in the above code, You have created a folder. And just like node(npm) init. You have initialized a module with the name `github.com/deepakshrma/todo_app`. The module name can be anything. However, It is recommended to use your module hosting platform(here, in this case, github.com) followed by the username and app name. 

Once you run the above command You can see a file will be created with the name `go.mod`. This will have all the dependencies and settings required by this app. You can read more on `go.mod` [here](https://golang.org/doc/modules/managing-dependencies). You can also watch [EVERYTHING You SHOULD know about Go Modules ](https://www.youtube.com/watch?v=Z1VhG7cf83M), a nice video tutorial on youtube.

```bash
cat go.mod

## output
module github.com/deepakshrma/todo_app

go 1.16
```

## Golang task manager, Build something new

Golang does not have an in-built task manager like the npm package. However, there is plenty of third-party modules available in the Golang world. I tried [go-task](https://taskfile.dev/#/) module and I loved it. So we can use the same.

#### Create a `Taskfile.yml` in root folder

```YAML
version: "3"

tasks:
  build-app:
    cmds:
      - go build -o todo_app.exe main.go
    silent: true
```
To use [go-task](https://taskfile.dev/#/), you have to install the binary. There are many ways you can install `task` binary. However, I recommend using the command `go get -u github.com/go-task/task/v3/cmd/task`. It will download go-task and create a binary in GOPATH. After that, you can use the task command globally.

#### Build using task

```bash
task build-app
```

## Write your first micro-service

A micro-service(web service) can follow different architecture. For the demo, I will use the RESTfull API. You can find relevant doc for GRPC [here](https://grpc.io/).

Update `main.go` file

```go
package main

// import net/http module

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

// Route function to handle the request

func handleFunc(w http.ResponseWriter, req *http.Request) {
	fmt.Fprint(w, "Hello, Golang ❤️")
}

func main() {

	// Get the user provided port from ENV, if port is not defined user default port as 8080
	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}

	// Bind "/" as route to handleFunc
	http.HandleFunc("/", handleFunc)

	log.Printf("You app is running on http://localhost:%s", port)

	// Listen and Serve to localhost:port
	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
}
```
Add a task to `Tasklist.yml`

```yaml
version: "3"

tasks:
## rest of the tasks
  build-start:
    cmds:
      - go build -o todo_app.exe main.go && ./todo_app.exe
```
**Run app: ** Once you add the task, You can build and run the app using the command `task build-start`. After that, you can open the URL to any browser [http://localhost:8080](http://localhost:8080) to see your first RESTfull API.



## Implementing database repository

This article is just starting guideline. So, We will not use a real database to make the connection and save data. However to mimic the database let's create a repository. We will use an in-memory `array/slice` to contain data.

To create a simple database repository and add methods to insert and list Todo, Add the below code to the `todo_app/repository/repository.go` file. 

```go
package repository

import "time"

type Todo struct {
	Title       string    `json:"title"`
	Done        bool      `json:"done"`
	Description string    `json:"description"`
	CreatedAt   time.Time `json:"createdAt"`
}

type repository struct {
	db []Todo
}

var (
	r *repository
)

// This function will run one time when package is imported before anything else.
func init() {
	r = &repository{
		db: []Todo{},
	}
}

// Repository, Create public interface
type Repository interface {
	ListTodo() []Todo
	AddTodo(todo *Todo) Todo
}

// Repository, Get instance of singleton repository
func NewRepository() Repository {
	return r
}

func (r *repository) ListTodo() []Todo {
	return r.db
}

func (r *repository) AddTodo(todo *Todo) Todo {
	todo.CreatedAt = time.Now()
	r.db = append(r.db, *todo)
	return *todo
}
```

Here in the above code, We have exposed a [singleton instance](https://github.com/golang/lint/issues/210) of Repository. 

**Let's tryout in main.go, we will remove this code later**

```go
 package main

import (
	"fmt"

	"github.com/deepakshrma/todo_app/repository"
)

func main() {
	r := repository.NewRepository()
	r.AddTodo(&repository.Todo{
		Title:       "Write a blog on golang",
		Description: "//TODO",
		Done:        false,
	})
	todos := r.ListTodo()
	for _, todo := range todos {
		fmt.Printf("%+v\n", todo)
	}
}

```

If you try the above code in the main function, You will see come output `{Title: Write a blog on Golang Done:false Description://TODO CreatedAt:2021-03-27 14:16:00.03263 +0800 +08 m=+0.000465414}`. We will update our router later.

## Using a third-party module/package

We have created a simple route using `http.HandleFunc`. But managing multiple routes could be a challenge. And at the same time, we don't want to re-invent the wheel. Using a module in Golang is pretty simple. You can get any module from the Github repo. Let's use one of the best web framework modules [gin-gonic](https://github.com/gin-gonic/gin).

To get a go module, you can use `go get` command or you can use `go mod tidy` after adding code. 

```go
// main.go

package main

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

	"github.com/deepakshrma/todo_app/repository"
	"github.com/gin-gonic/gin"
)

var (
	r = repository.NewRepository()
)

func GetTodos(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{"data": r.ListTodo()})
}
func AddTodo(c *gin.Context) {
	var input repository.Todo
	if err := c.ShouldBindJSON(&input); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	r.AddTodo(&input)
	c.JSON(http.StatusOK, gin.H{"data": input})
}
func main() {
	// Get the user provided port from ENV, if port is not defined user default port as 8080
	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}
	router := gin.Default()
	v1 := router.Group("/v1")
	{
		v1.GET("/todos", GetTodos)
		v1.POST("/todos", AddTodo)
	}
	log.Fatal(router.Run(fmt.Sprintf(":%s", port)))
}
```

Run `go mod tidy` command and start the server

```bash
## get modules
go mod tidy

## build and start the server
 task build-start
``` 

**Note:** `go mod tidy` import module and same time clean up `go.mod` file by removing unused imports. It is a very handy command.

**Explanation:** Above code we have created a gin router with grouping them using API versioning. If you dot use Group, The default endpoint will be "/todos". But adding Group `v1`, Now all APIs need to add `v1` to request resources.

#### Insert a todo and get the list using curl
You can use postman to insert and get data. However, for simplicity, I will use the curl command.

**Insert data using endpoint**

```bash
curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"title":"Create Golang Tutorial","Description":"lets do it.."}' \
  http://localhost:8080/v1/todos
```

```json
// result

{"data":{"title":"Create Golang Tutorial","done":false,"description":"lets do it..","createdAt":"2021-03-27T14:54:56.796403+08:00"}}
```
**Fetch data using endpoint**

```bash
curl http://localhost:8080/v1/todos 
```

```json
// result

{"data":[{"title":"Create Golang Tutorial","done":false,"description":"lets do it..","createdAt":"2021-03-27T14:54:56.796403+08:00"}]}
```


![how to write a research paper conclusion (1)_1554820948.jpeg](https://cdn.hashnode.com/res/hashnode/image/upload/v1617273718465/5RATYEivE.jpeg)

## Conclusions, Where to go from here

Finally, We have a working Micro Service. Definitely, This is not the perfect one. There are some other topics that need to be cover like Testing. However, It will give a kick start to write code in Golang. And thanks to the good community, You will find lots of nice document over the internet written by experts. Some article has been listed below.

#### References:

- [getting-started](https://golang.org/doc/tutorial/getting-started)
- [effective_go](https://golang.org/doc/effective_go)
- [gobyexample](https://gobyexample.com)
- [Golang-SQLite-Simple-Example](https://www.codeproject.com/Articles/5261771/Golang-SQLite-Simple-Example)
- [design-patterns](http://blog.ralch.com/tutorial/design-patterns/golang-singleton/)
- [golang-using-gin](https://blog.logrocket.com/how-to-build-a-rest-api-with-golang-using-gin-and-gorm/)

**Source Code:**


%[https://github.com/deepakshrma/golang-basics/tree/main/todo_app]



**Quotes Of The Day:**

> Writing a micro-server is an art and to make good Art, Artist needs a good tool. Go is one of those tools. - Me 😂


