Build your first service in golang
Tags: go, devfest, google, beginners
Published: 2021-12-09 17:07:14



## Overview

Go delivers speed, security, and developer-friendly tools for Web Applications

Go is designed to enable developers to rapidly develop scalable and secure web applications. Go ships with an easy to use, secure and performant web server and includes its own web templating library. Go has excellent support for all of the latest technologies from HTTP/2, to databases like MySQL, MongoDB and ElasticSearch, to the latest encryption standards including TLS 1.3. Go web applications run natively on Google App Engine and Google Cloud Run (for easy scaling) or on any environment, cloud, or operating system thanks to Go’s extreme portability.

[Go for Web Development](https://go.dev/solutions/webdev)
[What is a web service (REST API)](https://www.geeksforgeeks.org/rest-api-introduction/)

## Setup environment

**installing Golang**

go to the [official documentation](https://go.dev/doc/install) and follow the steps to install golang on your machine.

**installing a code editor**

You can use one of the available IDEs like [Goland](https://www.jetbrains.com/go/promo/?source=google&medium=cpc&campaign=10156131491&gclid=Cj0KCQiAzMGNBhCyARIsANpUkzNYDQZU2dLRAsrcy1Sd6VmpPCyENEKfekSmA0Xnlk_BgTde6JheOUgaAtccEALw_wcB) from [JetBrains](https://www.jetbrains.com/).
But I personally prefer using [Visual Studio Code](https://code.visualstudio.com/) editor because it's lightweight compared to IDEs and it combines the simplicity of a source code editor with powerful developer tooling, like IntelliSense code completion and debugging.

[Go in VSCode: Must-have extensions](https://dev.to/vuong/go-in-vscode-must-have-extensions-4jel)

## Let's Go

- Start by creating a `main.go` file in your project root folder.

In this file we are going to define the main package and the main function (entry point of any golang program)

```go
package main



func main() {
	
}
```
[Packages in go](https://go.dev/tour/basics/1)
[Functions in go](https://go.dev/tour/basics/4)

- Now we are going to create our project module ([introduction to golang modules](https://www.bogotobogo.com/GoLang/GoLang_Modules_1_Creating_a_new_module.php))
run the flowing command in the cmd (inside you project directory):

```
go mod init devfest.com/gopher
```

A new file will be added in your project directory named `go.mod` in wich you will find the module name golang version

in my case: 

```go
module devfest.com/gopher

go 1.17

```

**Let's set up our server**

- We start by creating a new package(folder) named `server`.
In this package we create a new file `http.go`, in this file we will implement the server setup and start functions and we will handle our first request.

We add the package name and define an empty struct called `HttpService` ([structs in go](https://gobyexample.com/structs))

```go
package server

type HttpService struct{
	
}
```

- Than we implement the server Start function:
1. We define the function signature

```go
func  Start() {}
```

2. We print message to the console to indicate that the server is starting and mention the port the server is going to run on

```go
func  Start() {
	fmt.Printf("Starting server at port %s\n", ":8080")
}
```
We used the [fmt](https://pkg.go.dev/fmt) package so we can use the Printf function thus we need to import it.

```go
import "fmt"
```

We can see above that the function Start begins with a capital letter (as well as the Printf func from the fmt package) wich is unusual for someone comming from a different programming language especially an OOP language, in fact methods in Go are exported by capitalizing its first letter.
[Exported names](https://go.dev/tour/basics/3)

3. We then use the function ListenAndServe function from the [net/http package](https://pkg.go.dev/net/http) which starts a golang server on a provided port 

```go
func  Start() {
	fmt.Printf("Starting server at port %s\n", ":8080")
	err := http.ListenAndServe(fmt.Sprintf(":%s", "8080"), nil) 
	if err != nil {
		log.Println(err)
	}
}
```

We can see the new `:=` annotation it's a [short variable declaration operator in go ](https://www.geeksforgeeks.org/short-variable-declaration-operator-in-go/).
The function ListenAndServe returns an error so we handle it by checking if it's not nil (null) we log it.

4. we add a receiver to the start function to assign it to the HttpService struct:
([Method receivers](https://www.golangbootcamp.com/book/methods#:~:text=Go%20does%20not%20have%20classes)/
[Pointers](https://gobyexample.com/pointers))

```go
func  (svc *HttpService) Start() {
	fmt.Printf("Starting server at port %s\n", ":8080")
	err := http.ListenAndServe(fmt.Sprintf(":%s", "8080"), nil) 
	if err != nil {
		log.Println(err)
	}
}
```

- now let's implement the Setup function:

```go
func (svc *HttpService) Setup() {
	http.HandleFunc("/ping", ping)
}
```
The Setup function is exported and assigned to the HttpService. As we can see we called the function HundleFunc from the `net/http` package that registers a handler function for the given pattern (in our case /ping).

- We need to implement the ping function to handle the request on /ping:

```go
func ping(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Pong!")
}
```

ping starts with a lowercase letter so it's not exported thus it can only be called from the server `package`, it takes two params: r of type *http.Request (in which we can find all the request information) and w of type http.ResponseWriter (which will be used to return the response to the request sender). In the ping function we used the Fprintf of the fmt package to return a message using the ResponseWriter.

> don't forget to import the fmt package

`http.go` would look like this in the end:

```go
package server

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

type HttpService struct {
}

func (svc *HttpService) Setup() {
	http.HandleFunc("/ping", ping)
}

func ping(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Pong!")
}

func  (svc *HttpService) Start() {
	fmt.Printf("Starting server at port %s\n", ":8080")
	err := http.ListenAndServe(fmt.Sprintf(":%s", "8080"), nil) 
	if err != nil {
		log.Println(err)
	}
}

```

- Let's go back to `main.go` to create an instance of our server, configure it and run it.

- We start by importing the server package so we can get our server type and functions.

```go
import "devfest.com/gopher/server"
```
As we can see here we started the import by specifying the module name that we created in the beginning `devfest.com/gopher` then the package name to tell the compiler that we are going to import the server package from this module.

- Now we create a new variable of type `HttpService` of our server package, and we call the setup function to set up our server and the start function to start it.

```go
func main() {
	var server server.HttpService

	server.Setup()

	server.Start()
}

```
As we have assigned Setup and Start functions to `HttpService` struct we were able to call them by adding `.` after the variable after the variable name of type `server.HttpService`.

The main func would look like this in the end:

```go
package main

import "devfest.com/gopher/server"

func main() {
	var server server.HttpService

	server.Setup()

	server.Start()
}

```

## Let's test our server

- Now that we have implemented our first golang server it's time to test it.

run the flowing command in the cmd (inside you project directory): [two ways of running a go program](https://gobyexample.com/hello-world)

```
go run main.go
```

- After running this command we can see a message indicating that the server is starting at port 8080, then the cmd is freezing, which means that our server has started running and it's waiting for us to send a request for it to handle it.

![cmd](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/88b6g6bykdjchylniim0.png)
 
- We can now test our Server by heading to the browser and typing this url `http://localhost:8080/ping` and hit enter, the browser will issue a request to our server as it's running on the your device (localhost) at port 8080, than our server will redirect our request to the ping function, as we are sending the request on "/ping", and return the "Pong!" message that will be displayed on your browser tab.

![request from the browser](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kvks5obhyovrrrepiobs.png)
 

**Congratulations 🎉 you have just finished implementing your first golang server and you have learned a little about the language itself.**

## Conclusion

I hope this was helpful to guide you through building your first golang server and starting to discover the language by building something fun from scratch.
You can head over to the official  [Go](https://go.dev/doc/)  documentation to explore more about the language.
You can start with this [tutorial](https://go.dev/tour/welcome/1) that will help you discover the basics of the language.
And you can also see go used in different [examples](https://gobyexample.com/).