router

package module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 15, 2024 License: GPL-3.0 Imports: 2 Imported by: 0

README


Logo

Octo Go

Simple router for Go

Report Bug · Request Feature · Changelog

Table of Contents
  1. About The Project
  2. Getting Started
  3. Usage
  4. License
  5. Acknowledgments

About the project

Octo Go is a lightweight, high-performance router for creating robust HTTP endpoints in Go. It started its history as a router built entirely from scratch, but with the release of Go 1.22 Octo Go turned into a wrapper around the original mux, adding convenient creation of routes, middleware support and group routes. Octo Go is the perfect tool for simple creating powerful APIs in Go, staying as close to the original mux as possible, without unnecessary complexity.

back to top

Getting started

func main() {
  mux := router.NewRouter()

  mux.GET("/user", userGetHandler)
  mux.POST("/user", userPostHandler)

  http.ListenAndServe("localhost:3000", mux)

  // Registering route
  // METHOD: GET, POST, PUT, PATCH, DELETE
  // PATH: Route path e.g "/", "/users" or with parameters "/users/{id}", "/users/{id}/{group}"
  // HANDLER: func(w http.ResponseWriter, r *http.Request)
  // MIDDLEWARES: func(http.ResponseWriter, *http.Request, func()) you can add as many as you want

  mux.METHOD(PATH, HANDLER, MIDDLEWARES)

  // Registering global middleware
  // MIDDLEWARE: func(http.ResponseWriter, *http.Request, func())

  mux.Use(MIDDLEWARE)

  // Registering group of routes
  // BASE_PATH: default path for this group e.g "/products", all methods registered inside starts with this path

  mux.Group(BASE_PATH, func(mux *router.Router) {
    mux.METHOD(PATH, HANDLER, MIDDLEWARES)
  }, MIDDLEWARES)
}

Prerequisites

Go 1.22

Installation

go get -u github.com/4c65736975/octo-go

back to top

Usage

Routes

mux.GET("/", getHandler)
mux.PUT("/", putHandler)
mux.POST("/", postHandler)
mux.PATCH("/", patchHandler)
mux.DELETE("/", deleteHandler)

Group Routes

mux.Group("/users", func(mux *router.Router) {
  mux.GET("/", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "List all users")
  })
  mux.GET("/{id}", func(w http.ResponseWriter, r *http.Request) {
    id := r.PathValue("id")
    fmt.Fprintf(w, "Get user with ID %s\n", id)
  })
  mux.POST("/", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Create a new user")
  })
  mux.PUT("/{id}", func(w http.ResponseWriter, r *http.Request) {
    id := r.PathValue("id")
    fmt.Fprintf(w, "Update user with ID %s\n", id)
  })
  mux.DELETE("/{id}", func(w http.ResponseWriter, r *http.Request) {
    id := r.PathValue("id")
    fmt.Fprintf(w, "Delete user with ID %s\n", id)
  })
})

mux.Group("/products", func(mux *router.Router) {
  mux.GET("/", getProductsHandler)
  mux.GET("/{id}", getProductHandler)
  mux.POST("/", createProductHandler)
  mux.PUT("/{id}", updateProductHandler)
  mux.DELETE("/{id}", deleteProductHandler)
})

Middlewares

func exampleMiddleware(w http.ResponseWriter, req *http.Request, next func()) {
  fmt.Fprintln(w, "Example middleware")
  next()
}

If the next() function is not executed in the middleware, the request ends with this middleware, if it is executed, the next middleware or final handler is executed.

Global Middlewares
mux.Use(loggingMiddleware)
mux.Use(ipMiddleware)

Global middleware works on every registered route after adding global middleware, all routes added earlier are ignored

mux.GET("/products", productsHandler) // not using loggingMiddleware
mux.Use(loggingMiddleware)
mux.GET("/products/{id}", productHandler) // using loggingMiddleware
mux.DELETE("/products/{id}", deleteProductHandler) // using loggingMiddleware
Route Middlewares
mux.GET("/profile", profileHandler, authMiddleware)
mux.GET("/profile/settings", settingsHandler, authMiddleware, settingsMiddleware, usageMiddleware)
Group Middlewares
mux.Group("/users", func(mux *router.Router) {
  mux.GET("/", usersHandler)
  mux.DELETE("/{id}", deleteUserHandler, authMiddleware)
}, telemetryMiddleware)

Middlewares are executed in the order in which they are registered, unless the next() function is called before the middleware code as in the case below

mux.GET("/", routeHandler, localMiddleware, localMiddleware2, localMiddleware3, localMiddleware4)

func localMiddleware(w http.ResponseWriter, req *http.Request, next func()) {
  fmt.Println("Local middleware 1")
  next()
}

func localMiddleware2(w http.ResponseWriter, req *http.Request, next func()) {
  next()
  fmt.Println("Local middleware 2")
}

func localMiddleware3(w http.ResponseWriter, req *http.Request, next func()) {
  fmt.Println("Local middleware 3")
  next()
}

func localMiddleware4(w http.ResponseWriter, req *http.Request, next func()) {
  fmt.Println("Local middleware 4")
  next()
}

Console Output:
Local middleware 1
Local middleware 3
Local middleware 4
Local middleware 2

Parameters

With Go 1.22 we can register dynamic routes using the built-in mux. We can get the parameter in the handler or middleware as shown below.

mux.GET("/users/{id}/products/{category}", func(w http.ResponseWriter, r *http.Request) {
  fmt.Println("Handler")
  fmt.Println(req.PathValue("id"))
  fmt.Println(req.PathValue("category"))
}, testMiddleware)

func testMiddleware(w http.ResponseWriter, req *http.Request, next func()) {
  fmt.Println("Middleware")
  fmt.Println(req.PathValue("id"))
  fmt.Println(req.PathValue("category"))
  next()
}

Requested route: /users/1/products/human

Console Output:
Middleware
1
human
Handler
1
human

Query

We can access the query value as with the default mux and similarly to parameters, in the handler and middleware.

mux.GET("/users/{id}/products/{category}", func(w http.ResponseWriter, r *http.Request) {
  fmt.Println("Handler")
  fmt.Println(req.URL.Query())
  fmt.Println(req.URL.Query().Get("maxHeight"))
}, testMiddleware)

func testMiddleware(w http.ResponseWriter, req *http.Request, next func()) {
  fmt.Println("Middleware")
  fmt.Println(req.URL.Query())
  fmt.Println(req.URL.Query().Get("maxHeight"))
  next()
}

Requested route: /users/1/products/human?sort=asc&maxHeight=180

Console Output:
Middleware
map[maxHeight:[180] sort:[asc]]
180
Handler
map[maxHeight:[180] sort:[asc]]
180

back to top

License

Distributed under the GPL-3.0 license. See LICENSE for more information.

back to top

Acknowledgments

back to top

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Middleware

type Middleware func(http.ResponseWriter, *http.Request, func())

type Router

type Router struct {
	// contains filtered or unexported fields
}

func NewRouter

func NewRouter() *Router

NewRouter allocates and returns a new Router.

func (*Router) DELETE

func (r *Router) DELETE(path string, handler http.HandlerFunc, middlewares ...Middleware)

Creates DELETE endpoint with specified path, handler and middlewares

func (*Router) GET

func (r *Router) GET(path string, handler http.HandlerFunc, middlewares ...Middleware)

Creates GET endpoint with specified path, handler and middlewares

func (*Router) Group

func (r *Router) Group(path string, route func(router *Router), middlewares ...Middleware)

Creates group of endpoints with specified base path and middlewares

func (*Router) PATCH

func (r *Router) PATCH(path string, handler http.HandlerFunc, middlewares ...Middleware)

Creates PATCH endpoint with specified path, handler and middlewares

func (*Router) POST

func (r *Router) POST(path string, handler http.HandlerFunc, middlewares ...Middleware)

Creates POST endpoint with specified path, handler and middlewares

func (*Router) PUT

func (r *Router) PUT(path string, handler http.HandlerFunc, middlewares ...Middleware)

Creates PUT endpoint with specified path, handler and middlewares

func (*Router) ServeHTTP

func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)

func (*Router) Use

func (r *Router) Use(middleware Middleware)

Addes specified global middleware

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL