httprouter
httprouter copied to clipboard
Handle sub routing to separate http request
I want to execute code for two big routes like:
/admin and /
Any route begins with /admin will be execute functions like load json for admin, load template for admin ... and other route '/' will load different resources for avoiding load both frontend and backend.
How i do it with httprouter?
package main
import (
"fmt"
"net/http"
"strings"
"github.com/julienschmidt/httprouter"
)
// AdminResource simulates admin-specific resources (e.g., JSON, template)
type AdminResource struct {
JSONData string
TemplateData string
}
// FrontendResource simulates frontend-specific resources (e.g., JSON, template)
type FrontendResource struct {
JSONData string
TemplateData string
}
// loadAdminJSON simulates loading admin JSON data
func loadAdminJSON() string {
return `{"admin": "config"}` // Mock JSON
}
// loadAdminTemplate simulates loading an admin template
func loadAdminTemplate() string {
return "admin_template.html" // Mock template
}
// loadFrontendJSON simulates loading frontend JSON data
func loadFrontendJSON() string {
return `{"frontend": "config"}` // Mock JSON
}
// loadFrontendTemplate simulates loading a frontend template
func loadFrontendTemplate() string {
return "frontend_template.html" // Mock template
}
// adminMiddleware loads admin-specific resources and attaches them to the request
func adminMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
// Load admin resources
adminRes := AdminResource{
JSONData: loadAdminJSON(),
TemplateData: loadAdminTemplate(),
}
fmt.Printf("Admin middleware: Loaded JSON=%s, Template=%s\n", adminRes.JSONData, adminRes.TemplateData)
// In a real app, store resources in request context or pass to handler
// For simplicity, we just call the next handler
next(w, r, ps)
}
}
// frontendMiddleware loads frontend-specific resources and attaches them to the request
func frontendMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
// Load frontend resources
frontendRes := FrontendResource{
JSONData: loadFrontendJSON(),
TemplateData: loadFrontendTemplate(),
}
fmt.Printf("Frontend middleware: Loaded JSON=%s, Template=%s\n", frontendRes.JSONData, frontendRes.TemplateData)
// Call the next handler
next(w, r, ps)
}
}
// wrapHandler converts a standard http.HandlerFunc to an httprouter handler
func wrapHandler(h http.HandlerFunc, middleware func(http.HandlerFunc) http.HandlerFunc) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
middleware(h)(w, r, ps)
}
}
// adminHandler handles specific admin routes
func adminHandler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
path := ps.ByName("path")
if path == "" {
path = "admin root"
}
fmt.Fprintf(w, "Admin route: /admin/%s\n", path)
}
// frontendHandler handles specific frontend routes
func frontendHandler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
path := ps.ByName("path")
if path == "" {
path = "root"
}
fmt.Fprintf(w, "Frontend route: /%s\n", path)
}
func main() {
// Create a new httprouter instance
router := httprouter.New()
// Admin routes: /admin/*path
// All routes under /admin use adminMiddleware
router.GET("/admin/*path", wrapHandler(adminHandler, adminMiddleware))
// Specific admin routes (optional, to demonstrate exact matches)
router.GET("/admin", wrapHandler(adminHandler, adminMiddleware))
router.GET("/admin/users", wrapHandler(adminHandler, adminMiddleware))
// Frontend routes: /*path
// All other routes use frontendMiddleware
router.GET("/*path", wrapHandler(frontendHandler, frontendMiddleware))
// Specific frontend routes (optional, to demonstrate exact matches)
router.GET("/", wrapHandler(frontendHandler, frontendMiddleware))
router.GET("/about", wrapHandler(frontendHandler, frontendMiddleware))
// Start the server
fmt.Println("Server listening on :8080")
if err := http.ListenAndServe(":8080", router); err != nil {
fmt.Printf("Server error: %v\n", err)
}
}