Golang echo framework REST API

wahyu eko hadi saputro
4 min readNov 1, 2020

--

Pada kesempatan kali ini saya akan menulis artike tentang go echo framework, echo framework ini sangat powerfull untuk membuat aplikasi REST. Untuk contoh aplikasi bisa di download dari git hub pada link berikut : https://github.com/wahyueko22/golang-app/tree/master/echo-crud. Untuk menjalankan aplikasi dari githubnya jalankan :

go run server.go

Prasyarat untuk mulai praktek go echo framework :

1. Install go dari https://golang.org/dl/

2. Install golang editor, missal VS code dari https://code.visualstudio.com/download

3. Install library dependency pakai CLI :

untuk echo framework : https://echo.labstack.com/

go get github.com/labstack/echo/v4 

untuk ORMnya : https://xorm.io/

go get xorm.io/xorm 

untuk koneksi DB postgre : https://github.com/lib/pq

go get github.com/lib/pq

untuk validator field input request API : https://godoc.org/github.com/go-playground/validator

go get github.com/go-playground/validator/v10 

Pada aplikasi REST API hal umum yang dibutuhkan biasanya : JWT, interceptor (intercept HTTP request untuk dicek authentication dan authorization), logging aplikasi, error handling (validasi input, common response API jika terjadi expected error dan lain lain), application context (context aplikasi yang bisa diakses di kodingan manapun, sebuah context aplikasi akan terbuat saat request masuk ke API dan terdestroy saat API mengembalikan response). Oke selanjutnya mari kita kupas satu satu :

1. JWT (JSON web token)

Untuk aplikasi REST JWT merupakan sesuatu yang wajib ada untuk keperluan authentifikasi dan authorisasi. Untuk menggunakan fitur JWT pada echo framework maka perlu meng-import library “github.com/dgrijalva/jwt-go”.

Untuk lebih detailnya bisa dilihat di https://echo.labstack.com/cookbook/jwt

contoh login API

2. Interceptor

Interceptor diecho framework disebut dengan istilah middleware, jika diaplikasi java web disebut dengan istilah filter. Interceptor disini maksudnya adalah sebelum request mengakses sebuah resource maka request ini diinspeksi / dicek, request ini authentikasinya valid apa tidak, request ini punya authorisasi untuk akses resource apa tidak.

Untuk explore lebih lanjut tentang middleware bisa merujuk ke : https://echo.labstack.com/middleware.

// JWT Middleware. middle is interceptor
e.Use(appMiddleware.JWTWithConfig(appMiddleware.JWTConfig{
SigningMethod: auth.SigningMethod,
SigningKey: []byte(auth.SecretKey),
Claims: &auth.JwtCustomClaims{},
Skipper: func(c echo.Context) bool {
if strings.HasSuffix(c.Path(), "/login") {
return true
}
return false
},
SuccessHandler: func(c echo.Context) {
user, ok := c.Get("user").(*jwt.Token)
if ok {
claims := user.Claims.(*auth.JwtCustomClaims)
//custom loader //https://echo.labstack.com/guide/context
appContext := c.(*common.AppContext)
user := &model.User{}
user.Name = claims.Name
appContext.User = user
fmt.Println(" Claim ID : ")
fmt.Println(claims.Id)
fmt.Println("Standart Claim ID: ")
fmt.Println(claims.StandardClaims.Id)
}
},
}))

Di atas adalah contoh interceptor untuk mengecek token authentikasi pada request. Pada kodingan diatas jika URL yang diakses adalah login maka diskip alias tidak perlu cek token authentikasi.

Ini contoh mengakses protected resource, jika mengakses protected resource tanpa token yang valid maka akan error

access protected resource tanpa token

3. Logging

Logging adalah me log aplikasi yang running, logging sangat penting untuk mentrace jika terjadi error pada aplikasi. Untuk lebih detailnya bisa merujuk ke : https://echo.labstack.com/middleware/logger. Berikut contoh konfigurasi / format untuk logging.

e := echo.New()//setting log levele.Logger.SetLevel(log.DEBUG)// format logging
myFile, err := os.Create("logApp.json")
if err != nil {
panic(err)
}
e.Use(appMiddleware.LoggerWithConfig(appMiddleware.LoggerConfig{
//Format: "method=${method}, uri=${uri}, status=${status} latency=${latency_human} in:${bytes_in} out:${bytes_out}\n",
//Skipper: DefaultSkipper,
Format: `{"time":"${time_rfc3339_nano}","id":"${id}","remote_ip":"${remote_ip}","host":"${host}",` +
`"method":"${method}","uri":"${uri}","status":${status},"error":"${error}","latency":${latency},` +
`"latency_human":"${latency_human}","bytes_in":${bytes_in},` +
`"bytes_out":${bytes_out}}` + "\n",
//Output: os.Stdout,
Output: myFile,
}))

4. Input validator dan common error handling untuk response

Pada setiap rest API pasti ada request dan ada response. API yang bagus itu adalah setiap ada request masuk maka field-field request akan divalidasi missal validasi nilai harus numeric, nilai tidak boleh null dan lain lain. Kemudian response API, response bagusnya juga informative, jangan setiap kali ada error aplikasi error baik handled error maupun unhandled error responsenya sama. Di echo framework kita juga bisa buat input validator dan custom response untuk error yang berbeda2.

Untuk custom validator bisa melihat merujuk ke : https://echo.labstack.com/guide/request#validate-data

Berikut sekilas contoh implementasi validator

//field validation https://godoc.org/github.com/go-playground/validator
custValidator := &common.CustomValidator{Validator: validator.New()}
err := custValidator.Init()
if err != nil {
fmt.Printf("Failed to init validator: %v\n", err)
os.Exit(1)
}
e.Validator = custValidator

untuk error hanler bisa merujuk ke link berikut https://echo.labstack.com/guide/error-handling

berikut contoh implementasi custom error handling

e.HTTPErrorHandler = common.CustomHTTPErrorHandler//isi dari common.CustomHTTPErrorHandlerfunc CustomHTTPErrorHandler(err error, c echo.Context) {
respCode := 500
resp := response.BasicResponse{}
resp.Success = false
resp.Message = ""
sendErrorResponse := func() {
// Send response
if !c.Response().Committed {
if c.Request().Method == http.MethodHead {
err = c.NoContent(respCode)
} else {
err = c.JSON(respCode, resp)
}
if err != nil {
c.Logger().Error(err)
}
}
}
validationErrors, ok := err.(validator.ValidationErrors)
if ok {
respCode = 407
resp.Message = "Validation errors"
resp.Errors = map[string]string{}
for _, ve := range validationErrors {
resp.Errors[ve.Field()] = "Contains unexpected value"
}
sendErrorResponse()
return
}
}
contoh hasil dari validasi jika field password kosong

5. Application context

application context makdsudnya adalah context aplikasi yang bisa diakses di kodingan manapun, sebuah context aplikasi akan terbuat saat request masuk ke API dan terdestoy saat API mengembalikan response. Kita bisa menaruh semua data yang dibutuhkan dalam 1 cycle dari request datang sampai ada response dalam application context, contoh kita bisa menaruh data userId dan username pada application context. Jika dipemprograman PHP mungkin mirip2 SESSION dan jika di java mirip2 object request, atau mirip localthread.

Untuk context application di echo framework bisa dilihat pada : https://echo.labstack.com/guide/context

Contoh implemntasi application context

//https://echo.labstack.com/guide/context
e.Use(func(h echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
//reference data
appContext := &common.AppContext{}
appContext.Context = c
return h(appContext)
}
})

Isi dari stuct application context

type AppContext struct {
echo.Context
User *model.User
}

Contoh cara memanggil application context

appContext := c.(*common.AppContext)
user := &model.User{}
user.Name = claims.Name
appContext.User = user

Sourcode : https://github.com/wahyueko22/golang-app/tree/master/echo-crud

Sumber :
https://echo.labstack.com/
https://xorm.io/
https://github.com/lib/pq
https://medium.com/@mfirmanakbar/tutorial-go-echo-web-framework-f50ef24ce7d4

--

--