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
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:
Configuring the webserver
To create the webserver we gonna use a lib called gin, 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:
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:
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:
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:
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:
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:
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
If you access message
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
Top comments (2)
Hello Augusto,
thanks to you I am learning Go, great !
Perhaps, I didn't read carrefully, but the first time I runned : go run main.go, shell said me : "main.go:4:2: no required module provides package github.com/augusto-queirantes/learning_go/config; to add it:
go get github.com/augusto-queirantes/learning_go/config"
I did and it worked !!!
Looking forward to the next step
Hey @geetee !
Good to know that you're learning Go with me!
The problem has already been resolved, I changed the code snipets that had problems. It happened because the controllers and config imports were pointing to my github instead of yours.
This king of problem happens cause go assumes that every git repository can be a lib, it doesn't need to be registered or anything else like npm.
In the end of the day, your problem was fixed when you executed the go get command cause you downloaded my code instead of using yours, you just have to change the import section on
main.go
andconfig/server.go
pointing to your github instead of mine.Let me know if this solution fixed your problem!