Init project
Tags: go, rest, gorm, swagger
Published: 2020-07-06 00:40:33

To start our project we will use this [github](https://github.com/MAAARKIN/hero-api-golang/tree/step-1) 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](https://github.com/golang-standards/project-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
```

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](https://blog.golang.org/using-go-modules).

```
go mod init github.com/maaarkin/hero-api-golang
```

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

```go
func main() {

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

```

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

```go
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)
}
```

To build our http server we will use [chi](https://github.com/go-chi/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.

```go
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"))
}
```

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.

```shell
λ curl http://localhost:8080/v1/books/hello
Hello World
```

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

```shell
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
```

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.