131 lines
3.1 KiB
Go
131 lines
3.1 KiB
Go
// Package api provides the HTTP server and routing for the banking service.
|
|
package api
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
|
|
"github.com/FernandoJVideira/simple_bank/internal/auth"
|
|
"github.com/FernandoJVideira/simple_bank/internal/config"
|
|
"github.com/FernandoJVideira/simple_bank/internal/domain/role"
|
|
"github.com/FernandoJVideira/simple_bank/internal/service"
|
|
"github.com/FernandoJVideira/simple_bank/internal/worker"
|
|
"github.com/rs/zerolog/log"
|
|
|
|
db "github.com/FernandoJVideira/simple_bank/internal/db/sqlc"
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"github.com/gin-contrib/cors"
|
|
swaggerFiles "github.com/swaggo/files"
|
|
ginSwagger "github.com/swaggo/gin-swagger"
|
|
)
|
|
|
|
// Server serves HTTP requests for our banking service.
|
|
type Server struct {
|
|
config config.Config
|
|
store db.Store
|
|
tokenMaker auth.Maker
|
|
router *gin.Engine
|
|
taskDisributor worker.TaskDistributor
|
|
httpServer *http.Server
|
|
userService service.UserService
|
|
authService service.AuthService
|
|
}
|
|
|
|
func NewServer(
|
|
config config.Config,
|
|
store db.Store,
|
|
taskDistributor worker.TaskDistributor,
|
|
tokenMaker auth.Maker,
|
|
userService service.UserService,
|
|
authService service.AuthService,
|
|
) (*Server, error) {
|
|
|
|
s := &Server{
|
|
config: config,
|
|
store: store,
|
|
tokenMaker: tokenMaker,
|
|
taskDisributor: taskDistributor,
|
|
userService: userService,
|
|
authService: authService,
|
|
}
|
|
|
|
// if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
|
|
// err := v.RegisterValidation("currency", validCurrency)
|
|
// if err != nil {
|
|
// return nil, err
|
|
// }
|
|
// }
|
|
|
|
s.setupRouter(config)
|
|
return s, nil
|
|
}
|
|
|
|
func (s *Server) setupRouter(config config.Config) {
|
|
router := gin.Default()
|
|
|
|
// Configure CORS middleware
|
|
router.Use(cors.New(cors.Config{
|
|
AllowOrigins: config.AllowedOrigins,
|
|
AllowMethods: []string{
|
|
http.MethodGet,
|
|
http.MethodPost,
|
|
http.MethodPut,
|
|
http.MethodPatch,
|
|
http.MethodDelete,
|
|
http.MethodOptions,
|
|
},
|
|
AllowHeaders: []string{
|
|
"Accept",
|
|
"Authorization",
|
|
"Content-Type",
|
|
"X-CSRF-Token",
|
|
},
|
|
AllowCredentials: true,
|
|
}))
|
|
|
|
router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
|
|
|
// Add routes
|
|
v1 := router.Group("/api/v1")
|
|
{
|
|
auth := v1.Group("/auth")
|
|
{
|
|
auth.POST("/login", s.loginUser)
|
|
auth.POST("/register", s.createUser)
|
|
auth.GET("/verify", s.verifyEmail)
|
|
auth.POST("/refresh", s.renewAccessToken)
|
|
}
|
|
|
|
user := v1.Group("/users")
|
|
{
|
|
me := user.Group("/me").Use(authMiddleware(s.tokenMaker, []string{role.AdminRole, role.MemberRole}))
|
|
{
|
|
me.GET("/", s.getCurrentUser)
|
|
me.PUT("/", s.updateUser)
|
|
me.PUT("/password", s.changePassword)
|
|
}
|
|
|
|
user.GET("/:username", s.getUser)
|
|
}
|
|
}
|
|
s.router = router
|
|
}
|
|
|
|
// Start runs the HTTP server on a specific address.
|
|
func (s *Server) Start(address string) error {
|
|
s.httpServer = &http.Server{
|
|
Addr: address,
|
|
Handler: s.router,
|
|
}
|
|
return s.httpServer.ListenAndServe()
|
|
}
|
|
|
|
func (s *Server) Shutdown(ctx context.Context) error {
|
|
log.Info().Msg("shutting down Gin HTTP server")
|
|
if s.httpServer != nil {
|
|
return s.httpServer.Shutdown(ctx)
|
|
}
|
|
return nil
|
|
}
|