Dalam pembuatan web, ada konsep yang bernama middleware atau interceptor, middleware adalah sebuah fitur dimana kita bisa menambahkan kode sebelum dan setelah sebuah handler di eksekusi.
Implementasi middleware
Sayangnya, digolang tidak ada middleware, namun karena struktur handler yang dibuat di golang menggunakan interface, kita bisa membuat middleware sendiri menggunakan handler.
Untuk mencobanya, buatlah file baru dengan nama middleware_test.go
dan isikan baris kode berikut
package belajar_golang_web
import (
"fmt"
"net/http"
"testing"
)
type LogMiddleware struct {
Handler http.Handler
}
func (middleware *LogMiddleware) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
fmt.Println("Before Execute Handler")
middleware.Handler.ServeHTTP(writer, request)
fmt.Println("After Execute Handler")
}
func TestMiddleware(t *testing.T) {
mux := http.NewServeMux()
mux.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
fmt.Println("Handler Executed")
fmt.Fprint(writer, "Hello Middleware")
})
logMiddleware := &LogMiddleware{
Handler: mux,
}
server := http.Server{
Addr: "localhost:8080",
Handler: logMiddleware,
}
err := server.ListenAndServe()
if err != nil {
panic(err)
}
}

Pada kode program diatas, kita membuat midleware di baris ke 13 yang mana mengimplementasikan interface Handler, dan di dalam middleware tersebut kita melakukan print sesudah dan sebelum handler di eksekusi. Kemudian penggunaan nya sendiri seperti pada baris 26 dan yang dikirim ke struct Server adalah middlewarenya. Request yang masuk nantinya akan seperti : request > middleware > handler
. Dan akan kembali ke client handler > middleware > request
Error handler
Kadang middleware juga bisa digunakan untuk melakukan error handler, hal ini sehingga jika terjadi panic di Handler, kita bisa melakukan recover di midleware, dan mengubah panic tersebut menjadi error response. Dengan ini, kita bisa menjaga aplikasi kita tidak berhenti berjalan.
Edit kembali file middleware_test.go
dan ubah semua baris kode nya seperti berikut
package belajar_golang_web
import (
"fmt"
"net/http"
"testing"
)
type LogMiddleware struct {
Handler http.Handler
}
type ErrorHandler struct {
Handler http.Handler
}
func (middleware *LogMiddleware) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
fmt.Println("Before Execute Handler")
middleware.Handler.ServeHTTP(writer, request)
fmt.Println("After Execute Handler")
}
func (errorHandler *ErrorHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
defer func() {
err := recover()
if err != nil {
fmt.Println("Terjadi error")
writer.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(writer, "Error %s", err)
}
}()
errorHandler.Handler.ServeHTTP(writer, request)
}
func TestMiddleware(t *testing.T) {
mux := http.NewServeMux()
mux.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
fmt.Println("Handler Executed")
fmt.Fprint(writer, "Hello Middleware")
})
mux.HandleFunc("/panic", func(writer http.ResponseWriter, request *http.Request) {
fmt.Println("Handler Executed")
panic("Ups")
})
logMiddleware := &LogMiddleware{
Handler: mux,
}
errorHandler := &ErrorHandler{
Handler: logMiddleware,
}
server := http.Server{
Addr: "localhost:8080",
Handler: errorHandler,
}
err := server.ListenAndServe()
if err != nil {
panic(err)
}
}

Kode program diatas sebenarnya sama saja dengan middleware yang sudah kita buat sebelumnya, hanya saja disini kita membuat struct baru sebagai midleware ErrorHandler
dan membuat middleware nya di baris 23. Kemudian penggunaan nya nanti akan menjadi dari errorHandler
akan mengirim request ke logMidleware
dan dari logMidleware
akan mengirim request ke mux
.
Penutup
Pada artikel kali ini kita telah belajar tentang middleware pada golang web. Dan pada artikel selanjutnya saya akan membahas routing library pada golang web.