Simple yet high performance Golang REST API Server Recipe — go-echo framework

Yuil Tripathee
4 min readSep 30, 2019

--

When it comes to concurrency, scalability, high performance, and speed, Golang holds it special position among the stacks out there. Here, I’ve tried GO REST API using echo framework which lets you serve simple JSON, Files and Media streaming, Static Server and even as a middle-ware to database server and your client program.

Also, I’ve built a boilerplate repository in GitHub so whenever I need RESTful service in my project, I can put it directly into the work.

Before we proceed, it is recommended to go through echo documentation: https://echo.labstack.com .

First things first, setup

Since I use Linux for most of my software development work, I used snap store for my golang installation, vscode is the code editor I use. So, I got those tools installed and finally, time to install echo framework itself; hit this in the terminal and you’ll get library installed into your system.

$ snap install go --classic // for installing golang$ snap install vscode // for installing visual studio code$ go get -u github.com/labstack/echo/... // to install echo library

If you’re using Windows or Mac, you can get installation guide in their documentation; so just Google it and get the setup done!

Let’s do some hello world

Now, let’s try to build hello world listener server (baby version of our API):

package mainimport (
"net/http"

"github.com/labstack/echo"
)
func main() {
e := echo.New()
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
})
e.Logger.Fatal(e.Start(":1323"))
}

Let’s see by running the above Go code:

$ go run server.go

You must be getting somewhat similar output as below it everything’s gone fine.

echo server (source: echo.labstack.com)

Browse to http://localhost:1323 and you should see Hello, World! on the page.

Static server

Let’s try setting out static file server. Now inside main() below the hello world handler, add the following code and you get your static server setup:

// static route for dummy landing page // Rule: e.Static("location of directory", "route for API")e.Static("static", "static")

Now, http://localhost:1323/static/* will serve static content, try out putting anything in the directory and you are able to access in your client (here, your brower).

Serving through multiple routes

Within the main() , below initialization of variable e , you can group routes as in the code below:

// list of endpoint routes 
APIRoute := e.Group("/api")
// grouping routes for version 1.0 API
v1route := APIRoute.Group("/v1")
// sample route to send normal JSON from program variable (route for API info)
v1route.GET("/", sendInfo)
// sample route to stream file
v1route.GET("/img/:id", sendImage)
// sample route to data transfer from database (MySQL here)
v1route.GET("/source/DB/", sendSampleDBData)
// sample route to data transfer from local JSON file
v1route.GET("/source/local/", sendSampleLocalData)

The syntax to define the route is as below:

e.METHOD("route", `handler function or name of handler function`)

Serving JSON from program variable

Golang allows us the data structure called map[key_datatype]value_datatype (sample data: {"id": 0} for map[string]integer ), which we can serve as JSON as the code below:

// route handler function for info route
func sendInfo(c echo.Context) error {
reqM := c.Request()
resM := c.Response()
return c.JSON(200, map[string]string{
"name": "REST_API_testing",
"developer": "John Doe",
"version": "v1.0",
"status_code": fmt.Sprintf("%d", resM.Status),
"time": time.Now().Format("2006/01/01 - 15:04:05"),
"protocol": reqM.Proto,
"ip": c.RealIP(),
"method": reqM.Method,
"url": fmt.Sprintf("%s", reqM.URL),
"bytes_out": fmt.Sprintf("%d", resM.Size),
"server_type": "Testing",
})
}

sendInfo() will handle route as above mentioned (check Grouping section). Just be careful to write this out of main() function.

Serving JSON from file storage

Let’s build a function that loads JSON file into program and a handler function to serve that JSON.

method that loads JSON from the given file address (click here)
route handler for sending JSON data from file to the HTTP client (click here)

Sending JSON from MySQL database table

For this purpose, let’s create a function that can read data from database using SELECT query and converts it to map[string]interface{}format which then will be served as JSON.

First, we will need database connection. Let’s create a string for it.

// function to generate database connection sting // final output sample: 
// root:password@tcp(127.0.0.1:3306)/database_name?charset=utf-8
func getConnectionString() string {

return dbusername + ":" + dbpassword + "@tcp(" + dbhostsip + ")/"
+ dbname + "?charset=" + dbcharset
}
// assigning to a string variablevar (
connectionString = getConnectionString()
)

Now, the function to get the data from database:

source: my own project (click here)

Here’s the function that change database data into GO’s readable data structure: https://github.com/yuil-plug-and-play/go-rest-api/blob/master/app/mysqldb.go

Now, here’s the route handler to pass the data to HTTP client:

route handler to pass data through the route (click here)

Serving file through the route

Now file is served simply by replacing c.JSON()used earlier by c.File("file address"). Let’s check the example below:

serving file after validation, just replace the string as you want

Final thoughts

Using Go, you can try other fantastic concepts like:

  1. Consuming Public API (e.g. OpenWeather, NASA OPEN API, …)
  2. ORM (check gorm.io)
  3. Stripe API for payment

Conclusion

You can get the entire project demonstrated above in this GitHub repository: https://github.com/yuil-plug-and-play/go-rest-api

--

--