Giter Site home page Giter Site logo

4c65736975 / octo-go Goto Github PK

View Code? Open in Web Editor NEW
1.0 2.0 0.0 59 KB

Octo Go is a lightweight, simple and customizable router for building a powerful HTTP endpoints in Go

License: GNU General Public License v3.0

Go 100.00%
api go golang http middleware mux mux-router router

octo-go's Introduction


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

octo-go's People

Contributors

4c65736975 avatar

Stargazers

 avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.