Golang Web App Development
Tags: go, webdev
Published: 2023-02-23 02:39:22



## Introduction
Go, or Golang, is a statically typed programming language released by Google in 2009. It is a backend programming language, which I am using to build a web app. It has extensive built-in packages and features, as well as the capability of adding third party packages. Some of these include **[net/http](https://pkg.go.dev/net/http)**, which includes the ability to listen on a port, route URLs and serve back content, **[html/template](https://pkg.go.dev/html/template)**, which has the ability to create Go templates out of HTML pages and dynamically passed data, and **[database/sql](https://pkg.go.dev/database/sql)**, which provides the ability to connect to a database. 

Using these packages, along with others, a developer can build a web app in Go.

Go has great **[documentation ](https://pkg.go.dev/std)** on the language and their packages, which I highly recommend checking out.

Below, I will demonstrate some of the abilities listed above, as well as some other interesting “quirks” about Go.

---

## Structure

All files must begin with a package declaration in the first line.
To run a program, it will need a main function, like Java's `main(String[] args)` method.

```
package main

func main() {
  // contents of the main function here
}
```

---


## Declarations
From a Java perspective, much of Golang can appear backwards. For example, in Java, declaration looks like:
![Java string and array](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q8ps4ib9vm2atavqm4sf.png)


As opposed to Go's...
![Golng string and slice](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x5uohz0p936comm5ksyj.png)



Go is very strict when it come to the "use it or loose it" mentality. If a variable or import is declared but not used, it must be deleted, or it will not compile.

![Can't compile unused variables](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hzuab1hpvy8iwxfad0e5.png)

Speaking of declarations, here are some examples of common declarations in Go. 
![Go declarations](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/djossrzmvsn8oqzjkbsp.png)

Now, developers can declare variables using the syntax above, but there are other ways.

```
// declare with type
var myString string
```
```
// declare with implied type
var myString = "Hello world"
```

This last one can only be used inside a block, such as a function.
```
// declare with ':='
myString := "Hello world"
```

---

## Using Packages
To import a package, simply declare `import()`, and list the imported packages in the parenthesis. 

To use functions and variables, write the package name, followed by `.` and the name of the thing you want.

```
// For example

import (
  "fmt"
)

fmt.Print("Hello World!")
```
Remember, use it or loose it. The file will not compile with unused imports.

To import third-party packages as well as other local packages, you will need to create a go.mod file. In the command line, type `go mod init {{project name}}` to create the go.mod file.


---

## Loops
While languages such as Java and JavaScript have for, while, and do…while loops, Go has one: the for loop. It is very easy to work with, but there are multiple ways of using it:

```
// The basic for loop:
for i := 0; i < 10; i++ {
}
```

```
// The foreach loop (slices and arrays):
for index, item := range mySlice {
}
```

```
// The foreach loop (maps):
for key, value:= range myMap {
}
```

```
// The foreach loop (channels):
for input := range myChannel {
}
```

```
// The while true loop:
for isTrue {
}
```

```
// The infinite loop:
for {
}
```

---

## Access
In Java, developers mark attributes and methods as _private_ or _public_ to control access. Go also allows developers to control access when exporting packages, but not with _public_ or _private_, but with case. If a function or variable begins with an _uppercase letter_, it is public. Otherwise, it is private.

```
var privateString = "no one can see this"
var PublicString = "other packages can see this."
```

---

## Objects _(sort of)_
Golang is not an _Object Oriented Programming_ language, but it does allow for functionality similar to object creation. This can be done by declaring custom types, based on the _struct_, short for structure. Functions can even have _receivers_, making them like methods, the `(u *User)` in this case.


![Golang custom type](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l84957ah4t7jo2mnvbia.png)

With receivers, the function must be attached to a variable of the type defined in the receiver place `(u *User)`. In the above example, one must declare a variable of type User and call the function from that.

```
var myUser User
myUser.WriteName
```
In the functionality, the receiver is referenced with the variable `u`.

---

## Arrays and Slices
We are all familiar with arrays. In languages like Java, the size of arrays are set, while in JavaScript, the size is dynamic. Golang has both. _Arrays_ have a set length, which can not be changed. A _slice_ is similar to an array, but it has variable length. They look very similar, but with one key difference: the value in the square brackets during declaration.

![Golang array and slice declaration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s1n0i7tkj8pmdqg19xoi.png)

A developer can also return a slice from the contents of an array/slice using index values in square brackets, returning all elements from the first listed index to the last (exclusive). The absence of a starting index means start at 0, and the absence of an ending index means end at the last element (inclusive).

```
// return elements at indexes [2,5)
newSlice := myArray[2:5]
```
```
// return elements at 2 to the end
newSlice := myArray[2:]
```
```
// return elements from the start to 5 (exclusive)
newSlice := myArray[:5]
```


---


## Random numbers
A big drawback of Golang is its random number generation. Using the **[math/rand](https://pkg.go.dev/math/rand)** package, there is a series of random value generators, but they all use the same seed, so the same numbers will be return in the same order each  time. To combat this, the developer must add a seed of his own. To get a unique seed, developers use the current date in the **[time](https://pkg.go.dev/time)** package, as that is always changing; thus, a different seed each time.

```
rand.NewSource(time.Now().UnixMicro())
randomInt := rand.Intn(10)
// return a number [0, 10)
```

---

## Functions
Functions work in Go the very similarly to Java and JavaScript. Declare with the `func` keyword, give the name, the parameters, the return and in the braces, give the functionality.

```
func equals (arg1 int, arg2 int) bool {
  return arg1 == arg2
}
```

Where Go gets interesting is with the receivers, talked about under **Objects**, and with the ability to have multiple return values.
These are put in parentheses after the parameters. The return statement must return both types listed, and when the return is being handled, both values must be accounted for.

```
func RandomString(x int, n int) (string, error)
```

```
// Handle string and error return values
output, err := util.RandomString(3, 3)
```
It is very common for functions in Go to return multiple values, one usually being an `error`, a type similar to Java's Exceptions.

Golang will not compile with unused variables, so what do developers do if a function has multiple return values, but they only care about one? In that case, developers use the `_` character. It means "I know a value is here, but I don't care about it.
```
// Ignore second return value
output, _ := util.RandomString(3, 3)
```

---

## Pointers
One thing to watch out for is pass-by-value. Golang is _entirely_ pass-by-value. This means every value you pass as an argument in a function will be copied into a new variable in a new place in memory. 

In other words, a variable passed as an argument will not be changed by the function, as the function is manipulating a different variable in a different place in memory.

Read this article on **[pass-by-value](https://david-yappeter.medium.com/golang-pass-by-value-vs-pass-by-reference-e48aac8b2716#:~:text=Pass%20by%20value%20will%20pass,created%20one%20into%20the%20method.)** for a better description than I can give.

![Pass-by-value demonstration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k7q3i9ymm22ejthvaamc.gif)



Developers can counteract this is by using pointers. Below, I demonstrate how to tell a function to expect a pointer and how to get a variable’s pointer.

The `*` before a type tells Go to expect a pointer to a value of the given type.
```
// Make a function that expects a pointer to a string and returns a pointer to an intager.
func usePointer (s *string) *int
```

To get a pointer to a variable, use the `&` character before the variable.

```
myString := "Hello World"
usePointer(&myString)
```

---

## Reference Types

Now that I've told you that Go is _entirely_ pass-by-value, let me tell you about the times it isn't.

Go really is entirely pass-by-value, but there are some datatypes known as reference types.
The **[article](https://david-yappeter.medium.com/golang-pass-by-value-vs-pass-by-reference-e48aac8b2716#:~:text=Referenced%20Data%20Type)** from **Pointers** talks about this.

These are types that don't directly store values (which is what value types do), but they instead store pointers. This means, even if the variable is copied, it still holds inside it a pointer to the actual value.

With reference types, developers do not need to get a pointer from them, as they _contain_ a pointer. They can be used as normal, no pointer required!


![Value and Reference types](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/br5ou3j4k9gh71kg6tu9.png)


---

## Routing
Using the **[net/http](https://pkg.go.dev/net/http)** package in the `main()` function, developers can route URLs.

```
http.HandleFunc("/URL", (func(res http.ResponseWriter, req *http.Request) {
		// handle responce and requests for /URL here
	}))
```
HanldeFunc requires a URL pattern in a string and a handler function that has `http.ResponseWriter` and `*http.Request` parameters. The function can be stored in another file or package, but it must be properly formatted and imported.

Another option for routing is to store the routes in another file or package using http.ServeMux.
You must make sure that the Mux variable is accessible to the listener (see **Listening**) by either making the variable public, or by making a public function that returns a pointer to the Mux variable.

```
Mux := http.NewServeMux()
Mux.HandleFunc("/URL", (func(res http.ResponseWriter, req *http.Request) {
		// handle responce and requests for /URL here
	}))
```

---

## Returning Go Templates
Developers can make Go templates using HTML pages. They can be simple static pages or complex dynamic pages. That topic is too big for this blog post, but I will demonstrate how to parse and return the file in a handle function (See **Routing**) using the **[html/template](https://pkg.go.dev/html/template)** package.

```
t, _ := template.ParseFiles("templates/index.html")
t.Execute(res, nil)
```

Notice the use of the `_` and the `nil`, which is a pointer to nothing, similar (although not the same) to the `null`.
The `res` variable used is of type `http.ResponseWriter`, the same one in the response handler.

---

## Listening

The most important part in web app development is the listener. Without it, it does not matter how advanced the app is, it is useless. This is also found in the **[net/http](https://pkg.go.dev/net/http)** package.

This is done with a very simple command in the `main()` function.
_(These examples will listen on port 3000)_

If using http.HanldeFunc for **Routing**:
```
http.ListenAndServe(":3000", nil)
```

If using http.ServeMux for **Routing**:
```
mux := http.NewServeMux()
// list routing functions here

http.ListenAndServe(":3000", mux)
```

---

## Conclusion

These have been some of the basics of Golang with a _very_ basic overview of web app development. Thank you for taking the time to read this blog post, and I would like to again recommend the Golang [documentation](https://pkg.go.dev/std). It is a great tool. There are also countless articles and videos about web app development. The ones I've read and seen are very good. It takes time and dedication, but it is not overly complex _(just another benefit of Golang)_.