├── .gitignore ├── resources ├── hello.txt └── goodbye.txt ├── go.mod ├── main.go ├── not_found_test.go ├── router_test.go ├── params_test.go ├── panic_test.go ├── method_not_allowed_test.go ├── middleware_test.go ├── go.sum ├── serve_file_test.go └── router_pattern_test.go /.gitignore: -------------------------------------------------------------------------------- 1 | .idea -------------------------------------------------------------------------------- /resources/hello.txt: -------------------------------------------------------------------------------- 1 | Hello HttpRouter -------------------------------------------------------------------------------- /resources/goodbye.txt: -------------------------------------------------------------------------------- 1 | Good Bye HttpRouter -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/ProgrammerZamanNow/belajar-golang-httprouter 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/julienschmidt/httprouter v1.3.0 // indirect 7 | github.com/stretchr/testify v1.7.0 // indirect 8 | ) 9 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/julienschmidt/httprouter" 6 | "net/http" 7 | ) 8 | 9 | func main() { 10 | router := httprouter.New() 11 | router.GET("/", func(writer http.ResponseWriter, request *http.Request, params httprouter.Params) { 12 | fmt.Fprint(writer, "Hello HttpRouter") 13 | }) 14 | 15 | server := http.Server{ 16 | Handler: router, 17 | Addr: "localhost:3000", 18 | } 19 | 20 | server.ListenAndServe() 21 | } 22 | -------------------------------------------------------------------------------- /not_found_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/julienschmidt/httprouter" 6 | "github.com/stretchr/testify/assert" 7 | "io" 8 | "net/http" 9 | "net/http/httptest" 10 | "testing" 11 | ) 12 | 13 | func TestNotFound(t *testing.T) { 14 | 15 | router := httprouter.New() 16 | router.NotFound = http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { 17 | fmt.Fprint(writer, "Gak Ketemu") 18 | }) 19 | 20 | request := httptest.NewRequest("GET", "http://localhost:3000/404", nil) 21 | recorder := httptest.NewRecorder() 22 | 23 | router.ServeHTTP(recorder, request) 24 | 25 | response := recorder.Result() 26 | body, _ := io.ReadAll(response.Body) 27 | 28 | assert.Equal(t, "Gak Ketemu", string(body)) 29 | 30 | } 31 | -------------------------------------------------------------------------------- /router_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/julienschmidt/httprouter" 6 | "github.com/stretchr/testify/assert" 7 | "io" 8 | "net/http" 9 | "net/http/httptest" 10 | "testing" 11 | ) 12 | 13 | func TestRouter(t *testing.T) { 14 | 15 | router := httprouter.New() 16 | router.GET("/", func(writer http.ResponseWriter, request *http.Request, params httprouter.Params) { 17 | fmt.Fprint(writer, "Hello World") 18 | }) 19 | 20 | request := httptest.NewRequest("GET", "http://localhost:3000/", nil) 21 | recorder := httptest.NewRecorder() 22 | 23 | router.ServeHTTP(recorder, request) 24 | 25 | response := recorder.Result() 26 | body, _ := io.ReadAll(response.Body) 27 | 28 | assert.Equal(t, "Hello World", string(body)) 29 | 30 | } 31 | -------------------------------------------------------------------------------- /params_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/julienschmidt/httprouter" 6 | "github.com/stretchr/testify/assert" 7 | "io" 8 | "net/http" 9 | "net/http/httptest" 10 | "testing" 11 | ) 12 | 13 | func TestParams(t *testing.T) { 14 | 15 | router := httprouter.New() 16 | router.GET("/products/:id", func(writer http.ResponseWriter, request *http.Request, params httprouter.Params) { 17 | id := params.ByName("id") 18 | text := "Product " + id 19 | fmt.Fprint(writer, text) 20 | }) 21 | 22 | request := httptest.NewRequest("GET", "http://localhost:3000/products/1", nil) 23 | recorder := httptest.NewRecorder() 24 | 25 | router.ServeHTTP(recorder, request) 26 | 27 | response := recorder.Result() 28 | body, _ := io.ReadAll(response.Body) 29 | 30 | assert.Equal(t, "Product 1", string(body)) 31 | 32 | } 33 | -------------------------------------------------------------------------------- /panic_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/julienschmidt/httprouter" 6 | "github.com/stretchr/testify/assert" 7 | "io" 8 | "net/http" 9 | "net/http/httptest" 10 | "testing" 11 | ) 12 | 13 | func TestPanicHandler(t *testing.T) { 14 | 15 | router := httprouter.New() 16 | 17 | router.PanicHandler = func(writer http.ResponseWriter, request *http.Request, error interface{}) { 18 | fmt.Fprint(writer, "Panic : ", error) 19 | } 20 | 21 | router.GET("/", func(writer http.ResponseWriter, request *http.Request, params httprouter.Params) { 22 | panic("Ups") 23 | }) 24 | 25 | request := httptest.NewRequest("GET", "http://localhost:3000/", nil) 26 | recorder := httptest.NewRecorder() 27 | 28 | router.ServeHTTP(recorder, request) 29 | 30 | response := recorder.Result() 31 | body, _ := io.ReadAll(response.Body) 32 | 33 | assert.Equal(t, "Panic : Ups", string(body)) 34 | 35 | } 36 | -------------------------------------------------------------------------------- /method_not_allowed_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/julienschmidt/httprouter" 6 | "github.com/stretchr/testify/assert" 7 | "io" 8 | "net/http" 9 | "net/http/httptest" 10 | "testing" 11 | ) 12 | 13 | func TestMethodNotAllowed(t *testing.T) { 14 | 15 | router := httprouter.New() 16 | router.MethodNotAllowed = http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { 17 | fmt.Fprint(writer, "Gak Boleh") 18 | }) 19 | router.POST("/", func(writer http.ResponseWriter, request *http.Request, params httprouter.Params) { 20 | fmt.Fprint(writer, "POST") 21 | }) 22 | 23 | request := httptest.NewRequest("PUT", "http://localhost:3000/", nil) 24 | recorder := httptest.NewRecorder() 25 | 26 | router.ServeHTTP(recorder, request) 27 | 28 | response := recorder.Result() 29 | body, _ := io.ReadAll(response.Body) 30 | 31 | assert.Equal(t, "Gak Boleh", string(body)) 32 | 33 | } 34 | -------------------------------------------------------------------------------- /middleware_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/julienschmidt/httprouter" 6 | "github.com/stretchr/testify/assert" 7 | "io" 8 | "net/http" 9 | "net/http/httptest" 10 | "testing" 11 | ) 12 | 13 | type LogMiddleware struct { 14 | http.Handler 15 | } 16 | 17 | func (middleware *LogMiddleware) ServeHTTP(writer http.ResponseWriter, request *http.Request) { 18 | fmt.Println("Receive Request") 19 | middleware.Handler.ServeHTTP(writer, request) 20 | } 21 | 22 | func TestMiddleware(t *testing.T) { 23 | 24 | router := httprouter.New() 25 | router.GET("/", func(writer http.ResponseWriter, request *http.Request, params httprouter.Params) { 26 | fmt.Fprint(writer, "Middleware") 27 | }) 28 | 29 | middleware := LogMiddleware{router} 30 | 31 | request := httptest.NewRequest("GET", "http://localhost:3000/", nil) 32 | recorder := httptest.NewRecorder() 33 | 34 | middleware.ServeHTTP(recorder, request) 35 | 36 | response := recorder.Result() 37 | body, _ := io.ReadAll(response.Body) 38 | 39 | assert.Equal(t, "Middleware", string(body)) 40 | 41 | } 42 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= 4 | github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= 5 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 6 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 7 | github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= 8 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 9 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 10 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 11 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 12 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 13 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 14 | -------------------------------------------------------------------------------- /serve_file_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "embed" 5 | "github.com/julienschmidt/httprouter" 6 | "github.com/stretchr/testify/assert" 7 | "io" 8 | "io/fs" 9 | "net/http" 10 | "net/http/httptest" 11 | "testing" 12 | ) 13 | 14 | //go:embed resources 15 | var resources embed.FS 16 | 17 | func TestServerFile(t *testing.T) { 18 | 19 | router := httprouter.New() 20 | directory, _ := fs.Sub(resources, "resources") 21 | router.ServeFiles("/files/*filepath", http.FS(directory)) 22 | 23 | request := httptest.NewRequest("GET", "http://localhost:3000/files/hello.txt", nil) 24 | recorder := httptest.NewRecorder() 25 | 26 | router.ServeHTTP(recorder, request) 27 | 28 | response := recorder.Result() 29 | body, _ := io.ReadAll(response.Body) 30 | 31 | assert.Equal(t, "Hello HttpRouter", string(body)) 32 | 33 | } 34 | 35 | func TestServerFileGoodBye(t *testing.T) { 36 | 37 | router := httprouter.New() 38 | directory, _ := fs.Sub(resources, "resources") 39 | router.ServeFiles("/files/*filepath", http.FS(directory)) 40 | 41 | request := httptest.NewRequest("GET", "http://localhost:3000/files/goodbye.txt", nil) 42 | recorder := httptest.NewRecorder() 43 | 44 | router.ServeHTTP(recorder, request) 45 | 46 | response := recorder.Result() 47 | body, _ := io.ReadAll(response.Body) 48 | 49 | assert.Equal(t, "Good Bye HttpRouter", string(body)) 50 | 51 | } 52 | -------------------------------------------------------------------------------- /router_pattern_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/julienschmidt/httprouter" 6 | "github.com/stretchr/testify/assert" 7 | "io" 8 | "net/http" 9 | "net/http/httptest" 10 | "testing" 11 | ) 12 | 13 | func TestRouterPatternNamedParameter(t *testing.T) { 14 | 15 | router := httprouter.New() 16 | router.GET("/products/:id/items/:itemId", func(writer http.ResponseWriter, request *http.Request, params httprouter.Params) { 17 | id := params.ByName("id") 18 | itemId := params.ByName("itemId") 19 | text := "Product " + id + " Item " + itemId 20 | fmt.Fprint(writer, text) 21 | }) 22 | 23 | request := httptest.NewRequest("GET", "http://localhost:3000/products/1/items/1", nil) 24 | recorder := httptest.NewRecorder() 25 | 26 | router.ServeHTTP(recorder, request) 27 | 28 | response := recorder.Result() 29 | body, _ := io.ReadAll(response.Body) 30 | 31 | assert.Equal(t, "Product 1 Item 1", string(body)) 32 | 33 | } 34 | 35 | func TestRouterPatternCatchAllParameter(t *testing.T) { 36 | 37 | router := httprouter.New() 38 | router.GET("/images/*image", func(writer http.ResponseWriter, request *http.Request, params httprouter.Params) { 39 | image := params.ByName("image") 40 | text := "Image : " + image 41 | fmt.Fprint(writer, text) 42 | }) 43 | 44 | request := httptest.NewRequest("GET", "http://localhost:3000/images/small/profile.png", nil) 45 | recorder := httptest.NewRecorder() 46 | 47 | router.ServeHTTP(recorder, request) 48 | 49 | response := recorder.Result() 50 | body, _ := io.ReadAll(response.Body) 51 | 52 | assert.Equal(t, "Image : /small/profile.png", string(body)) 53 | 54 | } 55 | --------------------------------------------------------------------------------