Learning GO - Creating the server - Part 2
Published: 2022-10-13 14:35:03

Hey guys! How are you? Hope everyone is ok!

This is the second part of a series of articles that will document my process of learning Go. In the past article we created a working environment and executed a hello world. In this article we'll configure a web server to see it working in a browser.

# Table of content

- [Go package managers](#go-package-managers)
- [Configuring the webserver](#configuring-the-webserver)
- [Creating the routes](#creating-the-routes)
- [Creating the controllers](#creating-the-controllers)
-- sad

# Go package managers

A package manager is a way to versionate the dependencies you want inside your application, that's the same as rails gems or npm packages.

To configure it we gonna execute the following commands inside the docker container:

```
go mod init
go mod init github.com/your_user/your_repo
```

You can execute any of the above commands, the difference is the module name, if you set your github repo as an argument this will be the module name, otherwise the module name will be `app`

After run the command you should see somehting like this as output:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wa93f317jvetau6dbi7d.png)

# Configuring the webserver

To create the webserver we gonna use a lib called [gin](https://github.com/gin-gonic/gin#installation), that's how we gonna configure it:

The first thing to do is download the lib, to do this we gonna execute the following command:

```
go get -u github.com/gin-gonic/gin
```

Once it's installed we need to import it on our main file, that's how it should looks like in the end of the day:

```go
package main

import (
  "net/http"
  "github.com/gin-gonic/gin"
)

func main() {
  webserver := gin.Default()

  webserver.GET("/", func(context *gin.Context) {
    context.JSON(http.StatusOK, gin.H{
      "message": "Hello, world!",
    })
  })

  webserver.Run(":3000")
}
```

You probably noticed that we had some changes in this file, they were:

- Change imports

We didnt's needed to import `fmt` package anymore cause we don't wanna the `print` function, so we removed it. Now we just import gin and net/http

- Refactor on main function

We completly refactored the main function, now it creates a webserver that has only one route that responds with a json. After creating this webserver we run this server on port 3000

If everything is ok you should see something like this when you access [this route](http://localhost:3000/):

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7lp6uhb003i0yy6et13i.png)

# Creating the routes

You may noticed that we have only one route on our application, that's a problem because I want to have as many routes as I can inside of a separeted file. To do this we gonna follow this proccess:

The first thing to do is create a file called `server.go` inside `config` folder, this file will contain our routes and execute them, that how it should look:

```go
package config

import (
  "github.com/gin-gonic/gin"

  "github.com/your_user/your_repo/controllers"
)

func Server() {
  router := gin.Default()

  router.GET("/", controllers.HomeIndex)
  router.GET("/message/:message", controllers.ShowMessage)

  router.Run(":3000")
}
```

This code imports gin and controllers (we'll talk about it soon) and has only one method, called `Server`, this method contains all routes and execute them in the end of the method, that's pretty much the same code that we have in our main.

You may noticed that when we create a route we gives the route's path as first argument and call a method as second argument, this method is instantiated in a controller and will everything we want this route to do.

For test purposes we'll create two routes, `/` and `/message`. The `/` route will always return `Hello world` and `/message` route will return a string that's given as parameter in the path.

# Creating the controllers

To respond to a route we'll use a controller, to create the controllers we'll need in this example follow this steps:

We'll need to create two files, `controllers/homeController.go` and `controllerrs/messageController.go`

The home controller will have the following code:

```go
package controllers

import (
  "net/http"
  "github.com/gin-gonic/gin"
)

func HomeIndex(context *gin.Context) {
  context.JSON(http.StatusOK, gin.H{"message": "Hello World!"})
}
```

This code just returns a json with the expected message, that's the same code we have in our main right now

The message controller will have the following code:

```go
package controllers

import (
  "net/http"
  "github.com/gin-gonic/gin"
)

func ShowMessage(context *gin.Context) {
  message := context.Param("message")

  context.JSON(http.StatusOK, gin.H{"message": message})
}
```

This code has the same structure with only one addition, it gets a params from the url and return it in the json.

Now we just need to change our main file to get everything working together, that's how it should looks like:

```go
package main

import (
  "github.com/your_user/your_repo/config"
)

func main() {
  config.Server()
}
```

The changes we made now is to import only the config folder and call the `Server` method we created before.

If everything is ok you should see something like this when execute `go run main.go`:

If you access [home](http://localhost:3000/)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wvwhz2sej6i28x9mmtau.png)

If you access [message](http://localhost:3000/message/test)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m3u5sec4g1qrq8s2d5tu.png)

Notice that the API returns `test` cause that's the argument we're giving, you can test it and see the result changing.

We'll guys, that's it! If there is any questions leave a comment! You can find the full code [here](https://github.com/augusto-queirantes/learning_go/pull/1)