Membuat Routing Menggunakan httprouter

Buka folder project menggunakan text editor favorit Anda, pada tutorial digunakan visual code editor.

Buat folder baru cmd/api. Kemudian buat file main.go didalamnya.

Perhatian, pemberian nama folder bisa berbeda, sesuaikan dengan kebiasan team Anda.

Lalu tambahkan code berikut pada main.go

package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"
	"time"
)

const ver = "1.0.0"

type config struct {
	port int
	env  string
}

type AppStat struct {
	Stat        string `json:"stat"`
	Environment string `json:"environment"`
	Version     string `json:"version"`
}

type application struct {
	config config
	logger *log.Logger
}

func main() {
	var cfg config

	flag.IntVar(&cfg.port, "port", 4000, "Server Port")
	flag.StringVar(&cfg.env, "env", "dev", "App env (dev|serv)")
	flag.Parse()

	logger := log.New(os.Stdout, "", log.Ldate|log.Ltime)

	app := &application{
		config: cfg,
		logger: logger,
	}

	srv := &http.Server{
		Addr:         fmt.Sprintf(":%d", cfg.port),
		Handler:      app.routes(),
		IdleTimeout:  time.Minute,
		ReadTimeout:  10 * time.Second,
		WriteTimeout: 30 * time.Second,
	}

	logger.Println("Starting server on port", cfg.port)
	err = srv.ListenAndServe()
	if err != nil {
		log.Println(err)
	}
}

kemudian tambahkan file routes.go, masukan code berikut

package main

import (
	"net/http"

	"github.com/julienschmidt/httprouter"
)

func (app *application) routes() *httprouter.Router {
	router := httprouter.New()

	router.HandlerFunc(http.MethodGet, "/status", app.statusHandler)

	return router
}

Selanjutnya buat file statusHandler.go, isi dengan code dibawah.

package main

import (
	"encoding/json"
	"net/http"
)

func (app *application) statusHandler(rw http.ResponseWriter, r *http.Request) {
	currStat := AppStat{
		Stat:        "Available",
		Environment: app.config.env,
		Version:     ver,
	}
	js, err := json.MarshalIndent(currStat, "", "\t")
	if err != nil {
		app.logger.Println(err)
	}
	rw.Header().Set("Content-Type", "application/json")
	rw.WriteHeader(http.StatusOK)
	rw.Write(js)
}

Jalankan program dengan perintah

$ go run cmd/api/main.go

Lalu buka path http://localhost/status, sesuai ekspektasi, pada browser akan ditampilkan informasi yang dihandle oleh fungsi statusHandler.

Pembahasan Code main.go

Pertama import library yang digunakan.

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"
	"time"
)

deklarasi constant dan struct yang akan digunakan pada project.

const ver = "1.0.0"

type config struct {
	port int
	env  string
}

type AppStat struct {
	Stat        string `json:"stat"`
	Environment string `json:"environment"`
	Version     string `json:"version"`
}

type application struct {
	config config
	logger *log.Logger

}

Pada fungsi main(), akan melakukan inisialisasi variable config.

Digunakan package standar flag, yang berfungsi menerima parameter options dari command line.

Perintah flag.IntVar(&cfg.port, “port”, 4000, “Server Port”), artinya program akan menerima input port dari command line (default value 4000 bila parameter tidak diinput pada command line).

Nilai port tersebut akan disimpan pada variable cfg.port. Perhatikan disini digunakan pointer.

	var cfg config

	flag.IntVar(&cfg.port, "port", 4000, "Server Port")
	flag.StringVar(&cfg.env, "env", "dev", "App env (dev|serv)")
	flag.Parse()

	logger := log.New(os.Stdout, "", log.Ldate|log.Ltime)

	app := &application{
		config: cfg,
		logger: logger,
	}

Kemudian buat instance http server dengan parameter

  • Addr: yang akan diisi dengan nilai dari cfg.port.
  • Handler: fungsi yang akan melakukan handling routing.
  • IdleTimeout, ReadTimeout dan WriteTimeout adalah parameter untuk mengatur server behaviour.

Setelah intance http.Server dibuat, lalu jalankan perintah srv.ListenAndServe() untuk menjalankan web server.


	srv := &http.Server{
		Addr:         fmt.Sprintf(":%d", cfg.port),
		Handler:      app.routes(),
		IdleTimeout:  time.Minute,
		ReadTimeout:  10 * time.Second,
		WriteTimeout: 30 * time.Second,
	}

	logger.Println("Starting server on port", cfg.port)
	err = srv.ListenAndServe()
	if err != nil {
		log.Println(err)
	}

Pembahasan Code routes.go

Import library yang digunakan

import (
	"net/http"

	"github.com/julienschmidt/httprouter"
)

Fungsi routes akan menangani request root dari client (web browser), lalu dilemparkan ke fungsi yang akan menangani route tersebut.

Pada contoh dibawah route /status akan ditangani oleh fungsi app.statusHandler.

func (app *application) routes() *httprouter.Router {
	router := httprouter.New()

	router.HandlerFunc(http.MethodGet, "/status", app.statusHandler)

	return router
}

Pembahasan code statusHandler.go

Import library yang digunakan.

import (
	"encoding/json"
	"net/http"
)

fungsi statusHandler akan mengembalikan json dari variable currStat.

Perhatikan saat mengembalikan response, kita harus mengatur header dan status response.

func (app *application) statusHandler(rw http.ResponseWriter, r *http.Request) {
	currStat := AppStat{
		Stat:        "Available",
		Environment: app.config.env,
		Version:     ver,
	}
	js, err := json.MarshalIndent(currStat, "", "\t")
	if err != nil {
		app.logger.Println(err)
	}
	rw.Header().Set("Content-Type", "application/json")
	rw.WriteHeader(http.StatusOK)
	rw.Write(js)
}

Sharing is caring:

Leave a Comment