๐Ÿ“ฆ aquaticcalf / fsrouter

โ˜… 1 stars โ‘‚ 0 forks ๐Ÿ‘ 1 watching โš–๏ธ MIT License
๐Ÿ“ฅ Clone https://github.com/aquaticcalf/fsrouter.git
HTTPS git clone https://github.com/aquaticcalf/fsrouter.git
SSH git clone git@github.com:aquaticcalf/fsrouter.git
CLI gh repo clone aquaticcalf/fsrouter
sam sam meow 3d64d2e 9 months ago ๐Ÿ“ History
๐Ÿ“‚ main View all commits โ†’
๐Ÿ“„ doc.go
๐Ÿ“„ go.mod
๐Ÿ“„ license.md
๐Ÿ“„ main.go
๐Ÿ“„ readme.md
๐Ÿ“„ README.md

fsrouter

A Go code generator that mirrors your api/ filesystem into HTTP routes using gorilla/mux.

Installation

go install github.com/aquaticcalf/fsrouter@latest

Usage

  • Structure your handlers under api/:
api/
  users/            # First-level directory becomes route group
    get.go          # exports func Get(w http.ResponseWriter, r *http.Request)
    [userId]/       # Dynamic parameter with [param] syntax
      get.go        # exports func Get(...)
      post.go       # exports func Post(...)
  auth/             # Another route group
    login/
      post.go       # exports func Post(...)

  • In your main.go, add:
//go:generate fsrouter -api=./api -out=routes_gen.go -pkg=main -importPREFIX=yourmodule/api -middleware=yourmodule/middleware -middlewares="loggingMiddleware,authMiddleware,corsMiddleware" -groupMiddlewares='{"users":"authMiddleware","admin":"adminAuthMiddleware,loggingMiddleware"}' -notFound=customHandlers.NotFound

package main

import (
    "log"
    "net/http"
)

func main() {
    r := RegisterRoutes() // generated
    log.Fatal(http.ListenAndServe(":3000", r))
}

  • Generate and build:
go generate ./...
go build ./...

Routes will be wired up from api/ files like get.go, post.go, etc.

Features

  • Automatic route registration from file system
  • Dynamic parameters with [param] folder syntax
  • Extensive Middleware Support
  • Multiple global middlewares for all routes
  • Group-specific middlewares for route groups
  • Flexible configuration via command line flags
  • Route grouping via first-level directories
  • Each top-level directory becomes a subrouter
  • Example: /api/users/... becomes a group
  • Custom 404 handler support
  • Specify with -notFound=package.Handler
  • Default JSON 404 handler included

Command Line Options

FlagDescriptionDefault
-apiDirectory of API handlersapi
-outOutput file pathroutes_gen.go
-pkgPackage name for generated filemain
-importPREFIXImport path prefix for API handlers(required)
-middlewarePackage containing middleware functions(optional)
-middlewaresComma-separated list of middleware functions to apply globallyloggingMiddleware
-groupMiddlewaresJSON mapping of group to middleware list(optional)
-notFoundCustom 404 handler (format: package.Handler)(default handler used)

Setting Up Middleware

Global Middleware

You can specify multiple global middlewares using the -middlewares flag:

fsrouter -middlewares="loggingMiddleware,authMiddleware,corsMiddleware"

Group-Specific Middleware

There are two ways to set up group-specific middleware:

  • Using the -groupMiddlewares flag with a JSON string:
fsrouter -groupMiddlewares='{"users":"authMiddleware,rateLimit","admin":"adminAuthMiddleware"}'

  • Editing the generated code (will be overwritten on regeneration):
// After generation, you can manually edit:
usersRouter.Use(authMiddleware)
adminRouter.Use(adminAuthMiddleware)

Creating Custom Middleware

Define your middleware functions in your application code:

// In your middleware package
func authMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Authentication logic here
        token := r.Header.Get("Authorization")
        if !validateToken(token) {
            http.Error(w, "Unauthorized", http.StatusUnauthorized)
            return
        }
        next.ServeHTTP(w, r)
    })
}

Extending

The generated code can be further customized as needed, but keep in mind that regeneration will overwrite your changes.

Use the command-line flags whenever possible to avoid manual edits.

Example Generated Router

// Example for a simple API structure
func RegisterRoutes() *mux.Router {
    r := mux.NewRouter()
    
    // Global middleware
    r.Use(loggingMiddleware)
    r.Use(authMiddleware)
    r.Use(corsMiddleware)
    
    // Route groups
    usersRouter := r.PathPrefix("/users").Subrouter()
    usersRouter.Use(authMiddleware)  // Group-specific middleware
    
    adminRouter := r.PathPrefix("/admin").Subrouter()
    adminRouter.Use(adminAuthMiddleware)
    adminRouter.Use(loggingMiddleware)
    
    authRouter := r.PathPrefix("/auth").Subrouter()
    
    // Routes
    usersRouter.HandleFunc("", users.Get).Methods("GET")
    usersRouter.HandleFunc("/{userId}", users_userId.Get).Methods("GET")
    adminRouter.HandleFunc("/dashboard", admin_dashboard.Get).Methods("GET")
    authRouter.HandleFunc("/login", auth_login.Post).Methods("POST")
    
    // 404 Handler
    r.NotFoundHandler = http.HandlerFunc(defaultNotFoundHandler)
    
    return r
}