diff --git a/README.md b/README.md index 73bba4b..6fbb6da 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Go API Template +![Version](https://img.shields.io/badge/version-1.0.5-blue) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) This is a production-ready Go backend API template designed to kickstart your next project. @@ -14,13 +15,7 @@ This is a production-ready Go backend API template designed to kickstart your ne - **Modular Structure**: Organized into `models`, `database`, `handlers`, `middleware`, `repositories`, and `services`. - **Testing System**: Includes a robust testing framework for unit and integration tests. -## Project Structure - -## Prerequisites - -- Go 1.23 or higher -- Docker and Docker Compose -- Make file +## Setup ### 1. Create a New Repository @@ -53,4 +48,3 @@ Contributions are welcome! Please open an issue or submit a pull request for any ## License This project is licensed under the **MIT License**. See the [LICENSE](LICENSE) file for details. - diff --git a/internal/api/handlers/user_handler.go b/internal/api/handlers/user_handler.go index a93c3d0..88a96c9 100644 --- a/internal/api/handlers/user_handler.go +++ b/internal/api/handlers/user_handler.go @@ -39,7 +39,7 @@ func CreateUser(userService services.UserService) http.HandlerFunc { // call here services - err = userService.CreateUser(user) + err = userService.CreateUser(&user) if err != nil { response.WriteJson(w, http.StatusInternalServerError, response.GeneralError(err)) return diff --git a/internal/api/middleware/auth_middleware.go b/internal/api/middleware/auth_middleware.go index 617610b..7c2adae 100644 --- a/internal/api/middleware/auth_middleware.go +++ b/internal/api/middleware/auth_middleware.go @@ -2,25 +2,26 @@ package middleware import ( "net/http" -) -func Auth(next http.Handler) http.HandlerFunc { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Extract the token from the request headers - token := r.Header.Get("Authorization") + "github.com/gauravst/go-api-template/internal/config" +) - if !isValidToken(token) { - http.Error(w, "Unauthorized", http.StatusUnauthorized) - return - } +func Auth(cfg *config.Config, authService *services.AuthService) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Extract the token from the request headers + cookie, err := r.Cookie("accessToken") + if err != nil { + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + token := cookie.Value - // If the token is valid, call the next handler - next.ServeHTTP(w, r) - }) -} + // refresh token + // logout or set new access token here based on status -func isValidToken(token string) bool { - // In a real application, you would validate the token against a database or a JWT library - // For this example, we'll assume the token is valid if it's not empty - return token != "" + // If the token is valid, call the next handler + next.ServeHTTP(w, r) + }) + } } diff --git a/internal/database/database.go b/internal/database/database.go index 5960cff..9c50262 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -10,11 +10,16 @@ import ( var DB *sql.DB func InitDB(uri string) { - DB, err := sql.Open("postgres", uri) + var err error + DB, err = sql.Open("postgres", uri) if err != nil { log.Fatalf("Error opening database: %v", err) } + if DB == nil { + log.Fatal("database connection is nil") + } + err = DB.Ping() if err != nil { log.Fatalf("Error connecting to the database: %v", err) diff --git a/internal/services/user_service.go b/internal/services/user_service.go index 9a3d753..0e37f17 100644 --- a/internal/services/user_service.go +++ b/internal/services/user_service.go @@ -9,9 +9,9 @@ import ( ) type UserService interface { - CreateUser(user models.User) error + CreateUser(user *models.User) error GetUserByID(id int) (*models.User, error) - UpdateUser(user models.User) error + UpdateUser(user *models.User) error DeleteUser(id int) error } @@ -25,12 +25,12 @@ func NewUserService(userRepo repositories.UserRepository) UserService { } } -func (s *userService) CreateUser(user models.User) error { +func (s *userService) CreateUser(user *models.User) error { if user.Name == "" { return errors.New("user name cannot be empty") } - err := s.userRepo.CreateUser(&user) + err := s.userRepo.CreateUser(user) if err != nil { return fmt.Errorf("failed to create user: %w", err) } @@ -49,12 +49,12 @@ func (s *userService) GetUserByID(id int) (*models.User, error) { } // UpdateUser updates an existing user -func (s *userService) UpdateUser(user models.User) error { +func (s *userService) UpdateUser(user *models.User) error { if user.Name == "" { return errors.New("user name cannot be empty") } - err := s.userRepo.UpdateUser(&user) + err := s.userRepo.UpdateUser(user) if err != nil { return fmt.Errorf("failed to update user: %w", err) } diff --git a/internal/utils/response/response.go b/internal/utils/response/response.go index 3fd8877..0dca64d 100644 --- a/internal/utils/response/response.go +++ b/internal/utils/response/response.go @@ -26,6 +26,10 @@ func WriteJson(w http.ResponseWriter, status int, data interface{}) error { return json.NewEncoder(w).Encode(data) } +func RedirectToURL(w http.ResponseWriter, r *http.Request, url string, status int) { + http.Redirect(w, r, url, status) +} + func GeneralError(err error) Response { return Response{ Status: StatusError, diff --git a/makefile b/makefile index 90e00ef..8ad1952 100644 --- a/makefile +++ b/makefile @@ -1,6 +1,10 @@ include .env export +# template migrate Variables +OLD_IMPORT=github.com/gauravst/go-api-template +OLD_CMD_DIR=cmd/go-api-template + # Variables BINARY_NAME=go-api-template GO_FILES=$(shell find . -name '*.go' -not -path './vendor/*') @@ -86,6 +90,29 @@ docker-all: docker-build docker-run # Run all checks (format, test, build) check: fmt test build +# template migrate +setup: + @echo "Enter your GitHub username :-" + @read USERNAME; \ + echo "Enter your project name :-"; \ + read PROJECT; \ + LOWER_USERNAME=$$(echo $$USERNAME | tr '[:upper:]' '[:lower:]'); \ + LOWER_PROJECT=$$(echo $$PROJECT | tr '[:upper:]' '[:lower:]'); \ + NEW_IMPORT=github.com/$$LOWER_USERNAME/$$LOWER_PROJECT; \ + NEW_CMD_DIR=cmd/$$LOWER_PROJECT; \ + echo "Replacing imports..."; \ + find . -type f -name "*.go" -exec sed -i 's|$(OLD_IMPORT)|'$$NEW_IMPORT'|g' {} +; \ + find . -type f -name "go.mod" -exec sed -i 's|$(OLD_IMPORT)|'$$NEW_IMPORT'|g' {} +; \ + find . -type f -name "go.sum" -exec sed -i 's|$(OLD_IMPORT)|'$$NEW_IMPORT'|g' {} +; \ + echo "Renaming main.go..."; \ + mkdir -p $$NEW_CMD_DIR; \ + mv $(OLD_CMD_DIR)/main.go $$NEW_CMD_DIR/main.go; \ + rm -rf $(OLD_CMD_DIR); \ + echo "Updating Makefile..."; \ + sed -i 's|OLD_IMPORT=$(OLD_IMPORT)|OLD_IMPORT='$$NEW_IMPORT'|g' makefile; \ + sed -i 's|OLD_CMD_DIR=$(OLD_CMD_DIR)|OLD_CMD_DIR='$$NEW_CMD_DIR'|g' makefile; \ + echo "Setup completed!" + # Help (list all targets) help: @echo "Available targets:" @@ -104,3 +131,4 @@ help: @echo " docker-rmi - Remove the Docker image" @echo " docker-clean - Clean up Docker resources (stop, remove container, and remove image)" @echo " docker-all - Build and run the Docker container" + @echo " setup - To Setup Project"