Simple yet high performance Golang REST API Server Recipe — go-echo framework
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.
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.
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-8func 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:
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:
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:
Final thoughts
Using Go, you can try other fantastic concepts like:
- Consuming Public API (e.g. OpenWeather, NASA OPEN API, …)
- ORM (check gorm.io)
- 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