Building Golang Restful API with Echo framework (part - 1)

Intro

This article is about how to build Golang restful api with echo framework (https://echo.labstack.com/).

Echo framework

Fast and unfancy HTTP server framework for Go (Golang). Up to 10x faster than the rest.
-echo

Echo is quite simple to build web application and Restful api. But, you might need to have experiences with other popular frameworks such as Ruby on rails, express.js and etc. Because, you need to design your app properly. This article is about how to design Restful api with echo framework.

In this article, I gonna use other Golang library such as GORM. It is mainly used for ORM for Golang.

Web application structure

Echo does not have skeleton generator like Beego and ROR. So, nobody structured your application before.

At first, you need to think about the folders and file structure for your project. I want to follow the MVC architecture. Based on MVC architecture, we should have models, views and controllers. For the Restful API, I think we might not need views.

Skeleton for Restful API

I will follow the folders structured as below.

app_name 
 — models
 — controllers
 — config
 — db
 — lib
 — server.go
 — config
 — db
 — lib

server.go

It is the entry point of your application. You can rename to different one. But, that file should be the main package for your application.

In Go programing, package are very important. Go program only can start on main package (“package main”)

package main
import (
"github.com/labstack/echo"
"github.com/labstack/echo/engine/standard"
"github.com/labstack/echo/middleware"
)
func main() {
e := echo.New()
 // Middleware
e.Use(middleware.Logger())
e.Use(middleware.Recover())
 //CORS
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"*"},
AllowMethods: []string{echo.GET, echo.HEAD, echo.PUT, echo.PATCH, echo.POST, echo.DELETE},
}))
// Server
e.Run(standard.New(":1323"))
}

In server.go, it should include the “main function()” which is the entry point of Go program. I imported 3 packages in server.go. They are:

  1. github.com/labstack/echo: echo package is to use echo framework
  2. “github.com/labstack/echo/engine/standard”: sub package from echo for web server.
  3. “github.com/labstack/echo/middleware”: sub package from echo for middleware

In main function:

I gonna start initialed the echo object with

e := echo.New()

The following code is using middleware in our application. Now I using three middleware:

// Middleware
e.Use(middleware.Logger())
e.Use(middleware.Recover())
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"*"},
AllowMethods: []string{echo.GET, echo.HEAD, echo.PUT, echo.PATCH, echo.POST, echo.DELETE},
}))
  • Recover is recover from panics anywhere in the chain.
  • Logger is for server log.
  • CORS gives web servers cross-domain access controls, which enable secure cross-domain data transfers.

You can also use another middleware and custom also. After that, I started echo web server on port 1323.

e.Run(standard.New(":1323"))

Now, app is running on localhost:1323. But, you might not see anything because of you don’t have handler to mange the request.

Let just create hander method in server.go

package main
import (
"github.com/labstack/echo"
"github.com/labstack/echo/engine/standard"
"github.com/labstack/echo/middleware"
)
func main() {
e := echo.New()
// Middleware
e.Use(middleware.Logger())
e.Use(middleware.Recover())
//CORS
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"*"},
AllowMethods: []string{echo.GET, echo.HEAD, echo.PUT, echo.PATCH, echo.POST, echo.DELETE},
}))
// Route => handler  e.GET("/", func(c echo.Context) error {       return c.String(http.StatusOK, "Hello, World!\n")  
})
// Server
e.Run(standard.New(":1323"))
}
// Route => handler  e.GET("/", func(c echo.Context) error {       return c.String(http.StatusOK, "Hello, World!\n")  
})

Now, if you go to localhost:1323, you will see html page with “Hello, Word”.

After that, i will create one controller for out application. Actually, echo does not need to create separated file for handler. For me, putting every hander methods in one file is very messy.

I will also give new package for controllers. I think that might be more cleaner. Let create the user.go rest controller file under controllers.

package controllers
import (
"github.com/labstack/echo"
"net/http"
)
//create user
func CreateUser(c echo.Context) error {
user := new(models.User)
var err error
return c.JSON(http.StatusCreated, user)
}

You can use that controller’s method in server.go as follow:

package main
import (
"echo_rest_app/controllers"
"github.com/labstack/echo"
"github.com/labstack/echo/engine/standard"
"github.com/labstack/echo/middleware"
)
func main() {
e := echo.New()
// Middleware
e.Use(middleware.Logger())
e.Use(middleware.Recover())
//CORS
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"*"},
AllowMethods: []string{echo.GET, echo.HEAD, echo.PUT, echo.PATCH, echo.POST, echo.DELETE},
}))
// Route => handler  e.GET("/", func(c echo.Context) error {       return c.String(http.StatusOK, "Hello, World!\n")  
})
 e.POST("/users", controllers.CreateUser)
// Server
e.Run(standard.New(":1323"))
}

In echo framework, there is separated struct each controller. It is just separated folder and package. So, you cannot give same method name through the whole package.