middlewares

This commit is contained in:
Jakub Kropáček 2024-11-17 22:52:24 +01:00
parent c3610ac1e4
commit bc5e37c747
7 changed files with 91 additions and 37 deletions

View file

@ -4,10 +4,8 @@ import (
"database/sql"
"git.katuwoss.dev/JustScreaMy/secret-santa/internal/app"
"git.katuwoss.dev/JustScreaMy/secret-santa/internal/config"
"log"
"net/http"
_ "github.com/mattn/go-sqlite3"
"log"
)
func main() {
@ -18,14 +16,9 @@ func main() {
log.Println("Database sucessfully connected")
appConfig := config.NewAppConfig(nil, nil)
application := app.NewApp(dbConnection, &appConfig)
application := app.NewApp(dbConnection, &appConfig, nil)
log.Printf("Listening on http://%s", appConfig.GenerateIP())
log.Fatal(
http.ListenAndServe(
appConfig.GenerateIP(),
application.Router(),
),
)
log.Fatal(application.Start())
}

View file

@ -3,24 +3,38 @@ package app
import (
"database/sql"
"git.katuwoss.dev/JustScreaMy/secret-santa/internal/config"
"git.katuwoss.dev/JustScreaMy/secret-santa/internal/middlewares"
"net/http"
)
type App struct {
Config config.AppConfig
DB *sql.DB
Server *http.Server
}
func NewApp(db *sql.DB, appConfig *config.AppConfig) *App {
defaultConfig := config.NewAppConfig(nil, nil)
func NewApp(db *sql.DB, appConfig *config.AppConfig, server *http.Server) *App {
if appConfig == nil {
defaultConfig := config.NewAppConfig(nil, nil)
appConfig = &defaultConfig
}
return &App{
app := &App{
Config: *appConfig,
DB: db,
}
if server == nil {
server = &http.Server{
Addr: app.Config.GenerateIP(),
Handler: app.Middlewares(app.Router()),
}
} else {
server.Handler = app.Router()
}
app.Server = server
return app
}
func (a *App) Router() http.Handler {
@ -30,3 +44,14 @@ func (a *App) Router() http.Handler {
return router
}
func (a *App) Middlewares(handler http.Handler) http.Handler {
stack := middlewares.CreateMiddlewareStack(
middlewares.Logging,
)
return stack(handler)
}
func (a *App) Start() error {
return a.Server.ListenAndServe()
}

View file

@ -5,7 +5,6 @@ import (
"database/sql"
"errors"
"git.katuwoss.dev/JustScreaMy/secret-santa/internal/queries"
"git.katuwoss.dev/JustScreaMy/secret-santa/internal/types"
"net/http"
)
@ -16,7 +15,7 @@ func HandleGetUsers(db *sql.DB) http.HandlerFunc {
users, err := query.GetUsers(ctx)
if err != nil {
writeErrorResponse(w, 500, err.Error())
writeErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
@ -24,7 +23,7 @@ func HandleGetUsers(db *sql.DB) http.HandlerFunc {
users = []queries.User{}
}
writeJSONResponse(w, 200, types.JsonResponse[[]queries.User]{Data: users})
writeJSONResponse(w, http.StatusOK, users)
}
}
func HandleGetUsersByID(db *sql.DB) http.HandlerFunc {
@ -34,20 +33,20 @@ func HandleGetUsersByID(db *sql.DB) http.HandlerFunc {
id, err := parseIDFromURL(r)
if err != nil {
writeErrorResponse(w, 500, err.Error())
writeErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
user, err := query.GetUserId(ctx, id)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
writeErrorResponse(w, 404, "User not found")
writeErrorResponse(w, http.StatusNotFound, "User not found")
return
}
writeErrorResponse(w, 500, err.Error())
writeErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
writeJSONResponse(w, 200, types.JsonResponse[queries.User]{Data: user})
writeJSONResponse(w, http.StatusOK, user)
}
}
@ -59,16 +58,16 @@ func HandleCreateUser(db *sql.DB) http.HandlerFunc {
var createUser queries.CreateUserParams
err := readJSONRequest(r, &createUser)
if err != nil {
writeErrorResponse(w, 500, err.Error())
writeErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
user, err := query.CreateUser(ctx, createUser)
if err != nil {
writeErrorResponse(w, 500, err.Error())
writeErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
writeJSONResponse(w, 201, types.JsonResponse[queries.User]{Data: user})
writeJSONResponse(w, http.StatusCreated, user)
}
}
@ -79,15 +78,15 @@ func HandleDeleteUser(db *sql.DB) http.HandlerFunc {
id, err := parseIDFromURL(r)
if err != nil {
writeErrorResponse(w, 500, err.Error())
writeErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
err = query.DeleteUser(ctx, id)
if err != nil {
writeErrorResponse(w, 500, err.Error())
writeErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
writeJSONResponse(w, 204, nil)
writeJSONResponse(w, http.StatusNoContent, nil)
}
}

View file

@ -2,7 +2,6 @@ package handlers
import (
"encoding/json"
"git.katuwoss.dev/JustScreaMy/secret-santa/internal/types"
"log"
"net/http"
"strconv"
@ -18,7 +17,9 @@ func writeJSONResponse(w http.ResponseWriter, statusCode int, data interface{})
}
func writeErrorResponse(w http.ResponseWriter, statusCode int, message string) {
writeJSONResponse(w, statusCode, types.ErrorResponse{Message: message})
writeJSONResponse(w, statusCode, map[string]string{
"error": message,
})
}
func readJSONRequest(r *http.Request, data interface{}) error {

View file

@ -0,0 +1,31 @@
package middlewares
import (
"log"
"net/http"
"time"
)
type wrappedWriter struct {
http.ResponseWriter
statusCode int
}
func (w *wrappedWriter) WriteHeader(statusCode int) {
w.statusCode = statusCode
w.ResponseWriter.WriteHeader(statusCode)
}
func Logging(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
startTime := time.Now()
wrapped := wrappedWriter{
ResponseWriter: w,
statusCode: http.StatusOK,
}
next.ServeHTTP(&wrapped, r)
elapsedTime := time.Since(startTime)
log.Println(r.Method, r.URL.Path, wrapped.statusCode, elapsedTime)
})
}

View file

@ -0,0 +1,14 @@
package middlewares
import "net/http"
type Middleware func(http.Handler) http.Handler
func CreateMiddlewareStack(middlewares ...Middleware) Middleware {
return func(next http.Handler) http.Handler {
for i := len(middlewares) - 1; i >= 0; i-- {
next = middlewares[i](next)
}
return next
}
}

View file

@ -1,9 +0,0 @@
package types
type JsonResponse[T any] struct {
Data T `json:"data"`
}
type ErrorResponse struct {
Message string `json:"message"`
}