09 Configuring HTTP Router, HTTP Server and Database Connection
At this stage we will create the main function of the project that we have created. In the main function we will add several function initializations which are used to initialize all the resources needed by the project such as database connections, handler initialization, usecases and repositories that we have previously created.
The HTTP Router that we use in this project is
1 github.com/julienschmidt/httprouterSo we need to first add the package to our project using the golang module command.
1 go get github.com/julienschmidt/httprouterConfiguring HTTP Router and HTTP ServerA
First, we create a main.go file in the cmd folder then fill the file with the code below.
1package cmd
2
3import (
4 "database/sql"
5
6 "github.com/julienschmidt/httprouter"
7 httpHandler "github.com/santekno/learn-golang-restful/delivery/http"
8 mysqlRepository "github.com/santekno/learn-golang-restful/repository/mysql"
9 articleUsecase "github.com/santekno/learn-golang-restful/usecase/article"
10)
11
12func main() {
13 router := httprouter.New()
14
15 repository := mysqlRepository.New(&sql.DB{})
16 articleUsecase := articleUsecase.New(repository)
17 articleHandler := httpHandler.New(articleUsecase)
18
19 router.GET("/api/articles", articleHandler.GetAll)
20 router.GET("/api/articles/:article_id", articleHandler.GetByID)
21 router.POST("/api/articles/", articleHandler.Store)
22 router.PUT("/api/articles/:article_id", articleHandler.Update)
23 router.DELETE("/api/articles/:article_id", articleHandler.Delete)
24
25 server := http.Server{
26 Addr: "localhost:3000",
27 Handler: router,
28 }
29
30 err := server.ListenAndServe()
31 if err != nil {
32 panic(err)
33 }
34}We can see that the first initialization done is
1 router := httprouter.New()httprouter initialization is done every time there is a REST API initialization if we use the package from julienschmidt/httprouter.Next we initialize the repository, usecase and handler layers that we have previously created.
1 repository := mysqlRepository.New(&sql.DB{})
2 articleUsecase := articleUsecase.New(repository)
3 articleHandler := httpHandler.New(articleUsecase)In initializing repository we need to add a database connection to the layer which will be explained in the database connection configuration section.
Followed by creating each endpoint that we previously defined using the API Specification. Make sure the method and entrypoint are the same as in the documentation.
1 router.GET("/api/articles", articleHandler.GetAll)
2 router.GET("/api/articles/:article_id", articleHandler.GetByID)
3 router.POST("/api/articles/", articleHandler.Store)
4 router.PUT("/api/articles/:article_id", articleHandler.Update)
5 router.DELETE("/api/articles/:article_id", articleHandler.Delete)And the last is the HTTP Server to make our REST API server public with a configuration like this.
1 server := http.Server{
2 Addr: "localhost:3000",
3 Handler: router,
4 }
5
6 err := server.ListenAndServe()
7 if err != nil {
8 panic(err)
9 }MySQL Database Connection Configuration
In this database connection we use an additional package to support connections to the MySQL database, namely
1github.com/go-sql-driver/mysql Then we need to add the package/libary first with this command.
1go get github.com/go-sql-driver/mysql Then we create the pkg/database folder and create the mysql.go file then fill the file with the code below.
1package database
2
3import (
4 "database/sql"
5 "os"
6
7 "gorm.io/driver/mysql"
8)
9
10unc New() *sql.DB {
11 cfg := mysql.Config{
12 User: os.Getenv("DATABASE_USER"),
13 Passwd: os.Getenv("DATABASE_PASS"),
14 Net: "tcp",
15 Addr: os.Getenv("DATABASE_ADDRESS"),
16 DBName: os.Getenv("DATABASE_NAME"),
17 AllowNativePasswords: true,
18 ParseTime: true,
19 }
20
21 var err error
22 db, err := sql.Open("mysql", cfg.FormatDSN())
23 if err != nil {
24 log.Fatal(err)
25 }
26
27 pingErr := db.Ping()
28 if pingErr != nil {
29 log.Fatal(pingErr)
30 }
31
32 fmt.Println("Connected!")
33 return db
34}In this project we only do basic configuration including
| Configuration | Information |
|---|---|
User | user connection required to mysql database |
Passwd | the passowrd for the user required for connection to the mysql database |
Net | the protocol used to connect to the database |
Addr | the address indicating the server of the database |
DBName | the name of the destination database |
Next add the database connection to the main.go file and change the main() function as below.
1func main() {
2 // initialize http router
3 router := httprouter.New()
4
5 // initialize database
6 db := database.New()
7
8 // initialize repository
9 repository := mysqlRepository.New(db)
10 // initialize usecase
11 articleUsecase := articleUsecase.New(repository)
12 // handler initialization
13 articleHandler := httpHandler.New(articleUsecase)
14
15 // entrypoint
16 router.GET("/api/articles", articleHandler.GetAll)
17 router.GET("/api/articles/:article_id", articleHandler.GetByID)
18 router.POST("/api/articles/", articleHandler.Store)
19 router.PUT("/api/articles/:article_id", articleHandler.Update)
20 router.DELETE("/api/articles/:article_id", articleHandler.Delete)
21}Create .env file
We will make all the configuration stored in one .env file so that when we want to change all the configuration it is easier and easier to just replace it in the file. So we will try to create a .env file and fill the file with this.
1DATABASE_USER=development
2DATABASE_PASS=d3v3l0pm3nt
3DATABASE_ADDRESS=localhost:3306
4DATABASE_NAME=articlethen add this library package to read the .env file
1go get github.com/joho/godotenvand add the code below to the main.go file at the top of the main() function.
1 err := godotenv.Load(".env")
2 if err != nil {
3 log.Fatalf("error loading .env file")
4 }