DEV Community

loading...
Cover image for Init project

Init project

Marcos Filho
A simple guy that love code
・3 min read

To start our project we will use this github to save our steps during the project.

In this first step we will define a folder structure, domain and controllers with a simple crud (GET, POST, PUT and DELETE).

First of all, we will see how our folder structure will be, after a lot of time reading articles and posts, creating projects and improving my code i decide to use a structure folder like golang standard layout with some changes.

Our Structure

In this first step our structure will look like this:

📦hero-api-golang
 ┣ 📂cmd
 ┃ ┗ 📂http
 ┃ ┃ ┣ 📂handler
 ┃ ┃ ┃ ┣ 📜book.go
 ┃ ┃ ┃ ┗ 📜router.go
 ┃ ┃ ┗ 📜main.go // Our entrypoint project
 ┣ 📜.gitignore
 ┣ 📜go.mod
 ┣ 📜go.sum
 ┗ 📜README.md
Enter fullscreen mode Exit fullscreen mode

In this post we will see all this files and improve this structure in the next post while we building our API.

Initializing the project

To initialize the golang project we need to start the goland dependency mananger, we will use the go mod.

go mod init github.com/maaarkin/hero-api-golang
Enter fullscreen mode Exit fullscreen mode

change /maaarkin/hero-api-golang to /your-user/your-project-name

Every application need a entrypoint, in our case we will represent by cmd/http/main.go file.

To minify the post, we will share only the code necessary to explain what we need, the complete code you can check in the github

func main() {

    //delegate to start our Http Server
    handler.StartServer()
}

Enter fullscreen mode Exit fullscreen mode

the StartServer() function manage everything that envolve http entrypoint like handler register, middleware register and error handler.

package handler

import (
    "github.com/go-chi/chi"
    "github.com/go-chi/chi/middleware"
    "log"
    "net/http"
)

type handlers struct {
    Book *BookHandler
}

func initHandlers() handlers {
    return handlers{
        Book: NewBookHandler(),
    }
}

func StartServer() {
    log.Println("Initializing the Http Server at localhost:8080")
    handlers := initHandlers()

    r := chi.NewRouter()

    r.Use(middleware.RequestID)
    r.Use(middleware.RealIP)
    r.Use(middleware.Logger)
    r.Use(middleware.Recoverer)

    r.Route("/v1", func(r chi.Router) {
        r.Route("/books", handlers.Book.Route)
    })
    http.ListenAndServe(":8080", r)
}
Enter fullscreen mode Exit fullscreen mode

To build our http server we will use chi, if you look the chi documentation you will see very similarities with our start code. The only difference here is that we separate the handler code to another file.

In this case you don't need the chi, the go provide a good http server but chi help us with a good idiomatic and composable router for building Go HTTP services, be free to choice anyone.

In initHandlers() we declare ours handlers, in other post i will tell you why we adopt this approach (IoC :D), but for now that function is responsible to group our API handlers.

And by now, check our BookHandler.

package handler

import (
    "github.com/go-chi/chi"
    "net/http"
)

type BookHandler struct{}

func NewBookHandler() *BookHandler {
    return &BookHandler{}
}

func (b *BookHandler) Route(r chi.Router) {
    r.Get("/hello", b.hello)
}

func (*BookHandler) hello(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusOK)
    w.Write([]byte("Hello World"))
}
Enter fullscreen mode Exit fullscreen mode

The Route(...) function that we use in the StartServer(...) provide an extension for /books. If we expose any endpoint to the client and this endpoint envolve book domain, we use this handler to expose the service.

To start the handler we will begin with a Hello World, just to check if the http server it's ok.

λ curl http://localhost:8080/v1/books/hello
Hello World
Enter fullscreen mode Exit fullscreen mode

If you check the server log, you will see something like this

2020/07/01 18:56:36 [LAPTOP-JNKKGDL0/hg3pWpHa7y-000002] "GET http://localhost:8080/v1/books/hello HTTP/1.1" from [::1]:50046 - 200 11B in 0s
Enter fullscreen mode Exit fullscreen mode

At this moment we have our http server started and we are ready to go to the next step, write our domain and service layer. But this content belongs to step-2.

Discussion (0)