시리즈: Go
go
101 줄
· 업데이트 2026-04-18
router.go
Go/Baasid/internal/router/router.go
// Package router registers all HTTP routes and middleware on a fresh Echo instance.
//
// Route layout mirrors the requirement document verbatim:
//
// POST /auth/login — public
// POST /goods/add — JWT required
// GET /goods — JWT required
// GET /goods/:id — JWT required
// PUT /goods/:id — JWT required
// DELETE /goods/:id — JWT required
//
// Swagger UI is mounted at /swagger/* for interactive exploration.
package router
import (
"net/http"
"baasid/internal/auth"
"baasid/internal/config"
"baasid/internal/handlers"
"baasid/internal/middleware"
"baasid/internal/repository"
"github.com/labstack/echo/v4"
echomw "github.com/labstack/echo/v4/middleware"
echoSwagger "github.com/swaggo/echo-swagger"
"gorm.io/gorm"
)
// NewEcho constructs the Echo engine with all routes wired.
func NewEcho(cfg *config.Config, db *gorm.DB) *echo.Echo {
e := echo.New()
e.HideBanner = true
e.HTTPErrorHandler = customHTTPErrorHandler
// Recover from panics (e.g. programming mistakes) and log stack traces.
e.Use(echomw.Recover())
// Request logger — invaluable when debugging JWT or DB issues locally.
e.Use(echomw.LoggerWithConfig(echomw.LoggerConfig{
Format: "${time_rfc3339} ${status} ${method} ${uri} latency=${latency_human}\n",
}))
// CORS: permissive defaults for local dev + Swagger UI in the browser.
e.Use(echomw.CORSWithConfig(echomw.CORSConfig{
AllowOrigins: []string{"*"},
AllowMethods: []string{http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete, http.MethodOptions},
AllowHeaders: []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept, echo.HeaderAuthorization},
}))
tokens := auth.NewTokenService(cfg.JWTSecret, "baasid", cfg.JWTExpiry)
users := repository.NewUserRepository(db)
goods := repository.NewGoodsRepository(db)
authH := handlers.NewAuthHandler(users, tokens)
goodsH := handlers.NewGoodsHandler(goods)
// Simple liveness probe for Docker / k8s health checks (not in the spec).
e.GET("/health", func(c echo.Context) error {
return c.JSON(http.StatusOK, echo.Map{"status": "ok"})
})
// Public authentication endpoint — no JWT required.
e.POST("/auth/login", authH.Login)
// Protected API group: every sub-route runs JWTAuth first.
protected := e.Group("", middleware.JWTAuth(tokens))
protected.POST("/goods/add", goodsH.Add)
protected.GET("/goods", goodsH.List)
protected.GET("/goods/:id", goodsH.GetByID)
protected.PUT("/goods/:id", goodsH.Update)
protected.DELETE("/goods/:id", goodsH.Delete)
// OpenAPI / Swagger UI (generated by swag into docs/ package).
e.GET("/swagger/*", echoSwagger.WrapHandler)
return e
}
// customHTTPErrorHandler renders echo.HTTPError as JSON when the client
// prefers JSON, which keeps Postman and Swagger responses consistent.
func customHTTPErrorHandler(err error, c echo.Context) {
if c.Response().Committed {
return
}
he, ok := err.(*echo.HTTPError)
if !ok {
he = &echo.HTTPError{Code: http.StatusInternalServerError, Message: http.StatusText(http.StatusInternalServerError)}
}
if he.Message == nil {
he.Message = http.StatusText(he.Code)
}
// Echo stores Message as interface{} — unwrap strings vs typed DTOs.
switch m := he.Message.(type) {
case string:
_ = c.JSON(he.Code, echo.Map{"message": m})
default:
_ = c.JSON(he.Code, m)
}
}
관련 글
Go
go
업데이트 2026-04-18
main.go
main.go — go source code from the Go learning materials (Go/Baasid/cmd/hashpw/main.go).
글 읽기 →
Go
go
업데이트 2026-04-18
main.go
main.go — go source code from the Go learning materials (Go/Baasid/cmd/server/main.go).
글 읽기 →
Go
go
업데이트 2026-04-18
docs.go
docs.go — go source code from the Go learning materials (Go/Baasid/docs/docs.go).
글 읽기 →
Go
go
업데이트 2026-04-18
jwt.go
jwt.go — go source code from the Go learning materials (Go/Baasid/internal/auth/jwt.go).
글 읽기 →
Go
go
업데이트 2026-04-18
password.go
password.go — go source code from the Go learning materials (Go/Baasid/internal/auth/password.go).
글 읽기 →
Go
go
업데이트 2026-04-18
password_test.go
password_test.go — go source code from the Go learning materials (Go/Baasid/internal/auth/password_test.go).
글 읽기 →