chore: use the echo framework instead of plain go net/http

This commit is contained in:
2025-06-02 17:35:07 +01:00
parent 4e6d939fd5
commit 9bd04f843a
8 changed files with 199 additions and 71 deletions
+21 -8
View File
@@ -1,16 +1,29 @@
package api
import "github.com/hazemKrimi/crimson-vault/internal/models"
import (
"github.com/hazemKrimi/crimson-vault/internal/models"
"github.com/labstack/echo/v4/middleware"
"github.com/labstack/echo/v4"
)
type APIWrapper struct {
dbWrapper *models.DBWrapper
type API struct {
instance *echo.Echo
db *models.DB
}
func (api *APIWrapper) Initialize() {
wrapper := models.DBWrapper{}
func (api *API) Initialize() {
db := &models.DB{}
ech := echo.New()
wrapper.Connect()
wrapper.MigrateClients()
db.Connect()
db.MigrateClients()
api.dbWrapper = &wrapper;
api.db = db
api.instance = ech
api.ClientRoutes()
api.instance.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"*"},
}))
api.instance.Logger.Fatal(api.instance.Start(":5000"))
}
+86 -34
View File
@@ -1,60 +1,112 @@
package api
import (
"encoding/json"
"fmt"
"log"
"net/http"
"strconv"
"github.com/hazemKrimi/crimson-vault/internal/models"
"github.com/labstack/echo/v4"
)
func (api *APIWrapper) CreateClientHandler(writer http.ResponseWriter, request *http.Request) {
func (api *API) CreateClientHandler(context echo.Context) error {
var body models.CreateClientBody
if err := json.NewDecoder(request.Body).Decode(&body); err != nil {
http.Error(writer, "Invalid JSON", http.StatusBadRequest)
if err := context.Bind(&body); err != nil {
log.Println(fmt.Sprintf("Error creating Client: %v.", err))
return
return context.String(http.StatusBadRequest, "Invalid JSON!")
}
client := api.dbWrapper.CreateClient(body)
client := api.db.CreateClient(body)
log.Println(fmt.Sprintf("Client created with ID %d.", client.ID))
json.NewEncoder(writer).Encode(client)
return context.JSON(http.StatusOK, client)
}
func (api *APIWrapper) GetClientsHandler(writer http.ResponseWriter, request *http.Request) {
idString := request.URL.Query().Get("id")
if idString != "" {
id, err := strconv.Atoi(idString)
if err != nil {
http.Error(writer, "Unexpected error getting Client.", http.StatusInternalServerError)
return
}
var client models.Client
if err := api.dbWrapper.GetClient(id, &client); err != nil {
http.Error(writer, "Client not found.", http.StatusNotFound)
return
}
log.Println(fmt.Sprintf("Got client with ID %d.", client.ID))
json.NewEncoder(writer).Encode(client)
return
}
clients, err := api.dbWrapper.GetClients()
func (api *API) GetAllClientsHandler(context echo.Context) error {
clients, err := api.db.GetClients()
if err != nil {
http.Error(writer, "Unexpected error getting Clients.", http.StatusInternalServerError)
return
return context.String(http.StatusInternalServerError, "Unexpected error getting Clients!")
}
log.Println("Got all Clients.")
json.NewEncoder(writer).Encode(clients)
return context.JSON(http.StatusOK, clients)
}
func (api *API) GetClientHandler(context echo.Context) error {
idString := context.Param("id")
if idString == "" {
return context.String(http.StatusBadRequest, "ID is required to get a Client!")
}
id, err := strconv.Atoi(idString)
if err != nil {
return context.String(http.StatusInternalServerError, "Unexpected error getting Client!")
}
var client models.Client
if err := api.db.GetClient(id, &client); err != nil {
return context.String(http.StatusNotFound, "Client not found!")
}
log.Println(fmt.Sprintf("Got client with ID %d.", client.ID))
return context.JSON(http.StatusOK, client)
}
func (api *API) UpdateClientHandler(context echo.Context) error {
idString := context.Param("id")
if idString == "" {
return context.String(http.StatusBadRequest, "ID is required to update a Client!")
}
id, err := strconv.Atoi(idString)
if err != nil {
return context.String(http.StatusInternalServerError, "Unexpected error updating Client!")
}
var body models.UpdateClientBody
if err := context.Bind(&body); err != nil {
log.Println(fmt.Sprintf("Error updating Client: %v.", err))
return context.String(http.StatusBadRequest, "Invalid JSON!")
}
var client models.Client
if err := api.db.UpdateClient(id, body, &client); err != nil {
return context.String(http.StatusNotFound, "Client not found!")
}
log.Println(fmt.Sprintf("Updated client with ID %d.", client.ID))
return context.JSON(http.StatusOK, client)
}
func (api *API) DeleteClientHandler(context echo.Context) error {
idString := context.Param("id")
if idString == "" {
return context.String(http.StatusBadRequest, "ID is required to delete a Client!")
}
id, err := strconv.Atoi(idString)
if err != nil {
return context.String(http.StatusInternalServerError, "Unexpected error deleting Client!")
}
var client models.Client
if err := api.db.DeleteClient(id); err != nil {
return context.String(http.StatusNotFound, "Client not found!")
}
log.Println(fmt.Sprintf("Deleted client with ID %d.", client.ID))
return context.String(http.StatusOK, "Client deleted successfully!")
}
+8 -9
View File
@@ -1,12 +1,11 @@
package api
import "net/http"
func ClientRoutes(api *APIWrapper) (*http.ServeMux) {
mux := http.NewServeMux()
mux.HandleFunc("GET /", api.GetClientsHandler)
mux.HandleFunc("POST /", api.CreateClientHandler)
return mux
func (api *API) ClientRoutes() {
group := api.instance.Group("/clients")
group.GET("/", api.GetAllClientsHandler)
group.POST("/", api.CreateClientHandler)
group.GET("/:id", api.GetClientHandler)
group.PUT("/:id", api.UpdateClientHandler)
group.DELETE("/:id", api.DeleteClientHandler)
}
+40 -8
View File
@@ -22,21 +22,27 @@ type CreateClientBody struct {
Phone string `json:"phone"`
}
func (wrapper *DBWrapper) MigrateClients() {
wrapper.db.AutoMigrate(&Client{})
type UpdateClientBody struct {
Name string `json:"name"`
Country string `json:"country"`
Phone string `json:"phone"`
}
func (wrapper *DBWrapper) CreateClient(body CreateClientBody) Client {
func (db *DB) MigrateClients() {
db.instance.AutoMigrate(&Client{})
}
func (db *DB) CreateClient(body CreateClientBody) Client {
client := Client{Name: body.Name, Country: body.Country, Phone: body.Phone}
wrapper.db.Create(&client)
db.instance.Create(&client)
return client
}
func (wrapper *DBWrapper) GetClients() ([]Client, error) {
func (db *DB) GetClients() ([]Client, error) {
var clients []Client
result := wrapper.db.Find(&clients)
result := db.instance.Find(&clients)
if result.Error != nil {
return nil, result.Error
@@ -45,8 +51,34 @@ func (wrapper *DBWrapper) GetClients() ([]Client, error) {
return clients, nil
}
func (wrapper *DBWrapper) GetClient(id int, client *Client) error {
result := wrapper.db.Where("id = ?", id).First(&client, id)
func (db *DB) GetClient(id int, client *Client) error {
result := db.instance.Where("id = ?", id).First(&client, id)
if result.Error != nil {
return result.Error
}
return nil
}
func (db *DB) UpdateClient(id int, body UpdateClientBody, client *Client) error {
result := db.instance.Where("id = ?", id).First(&client, id)
if result.Error != nil {
return result.Error
}
result = db.instance.Model(&client).Updates(Client{Name: body.Name, Country: body.Country, Phone: body.Phone})
if result.Error != nil {
return result.Error
}
return nil
}
func (db *DB) DeleteClient(id int) error {
result := db.instance.Delete(&Client{}, id)
if result.Error != nil {
return result.Error
+4 -4
View File
@@ -7,16 +7,16 @@ import (
"gorm.io/gorm"
)
type DBWrapper struct {
db *gorm.DB
type DB struct {
instance *gorm.DB
}
func (wrapper *DBWrapper) Connect() {
func (wrapper *DB) Connect() {
db, err := gorm.Open(sqlite.Open("crimson_vault.db"), &gorm.Config{})
if err != nil {
log.Fatal(err)
}
wrapper.db = db
wrapper.instance = db
}