diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 2e447c2..5746a60 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -15,7 +15,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: 1.20.4 + go-version: 1.21.3 - name: Format run: make tidy diff --git a/Dockerfile b/Dockerfile index 789a0de..1354eee 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.20-alpine AS build +FROM golang:1.21-alpine AS build ENV CGO_ENABLED=0 \ GOOS=linux \ diff --git a/Makefile b/Makefile index 8639d38..5c65309 100644 --- a/Makefile +++ b/Makefile @@ -24,3 +24,27 @@ up: down: docker-compose down + +ping: + curl http://localhost:3333/ping + +create-event: + curl -X POST \ + -H "Content-Type: application/json" \ + -d '{"name": "Random Event", "description": "a random test event", "category": "random", "location": "Buenos Aires", "publisher": "Nico", "lineup": ["Random Artits"], "start_ts": "2023-01-01T18:00:00Z","end_ts": "2023-01-01T21:00:00Z"}' \ + http://localhost:3333/bastet + +get-event: + curl http://localhost:3333/bastet/1 + +update-event: + curl -X PUT \ + -H "Content-Type: application/json" \ + -d '{"description": "Changed Description"}' \ + http://localhost:3333/bastet/1 + +delete-event: + curl -X DELETE http://localhost:3333/bastet/1 + +all-requests: + make create-event && make get-event && make update-event && make delete-event diff --git a/README.md b/README.md index 766b6d4..94e8fd0 100644 --- a/README.md +++ b/README.md @@ -23,36 +23,13 @@ DB_PORT=5432 ## Test the server Some basic curl commands are provided for convenience to actually test the server is operating right. -### PING -```bash -curl http://localhost:3333/ping -``` - -### POST -```bash -curl -X POST \ - -H "Content-Type: application/json" \ - -d '{"name": "Random Event", "description": "a random test event", "category": "random", "location": "Buenos Aires", "publisher": "Nico", "lineup": ["Random Artits"], "start_ts": "2023-01-01T18:00:00Z","end_ts": "2023-01-01T21:00:00Z"}' \ - http://localhost:3333/bastet -``` - -### GET -```bash -curl http://localhost:3333/bastet/1 -``` - -### UPDATE -```bash -curl -X PUT \ - -H "Content-Type: application/json" \ - -d '{"description": "Changed Description"}' \ - http://localhost:3333/bastet/1 -``` +1. Ping: `make ping` +2. Create an event: `make create-event` +3. Get an event: `make get-event` +4. Update an event: `make update-event` +5. Delete an event: `make delete-event` +6. Run CRUD: `make all-requests` -### DELETE -```bash -curl -X DELETE http://localhost:3333/bastet/1 -``` ## TBD 1. Deployment github workflow. diff --git a/cmd/bastet/main.go b/cmd/bastet/main.go index 4d6781d..13d33be 100644 --- a/cmd/bastet/main.go +++ b/cmd/bastet/main.go @@ -1,29 +1,29 @@ package main import ( + "log/slog" "os" "github.com/nanchano/bastet/internal/config" "github.com/nanchano/bastet/internal/core" "github.com/nanchano/bastet/internal/repository" "github.com/nanchano/bastet/internal/server" - "golang.org/x/exp/slog" ) func main() { - handler := slog.NewTextHandler(os.Stdout) + handler := slog.NewTextHandler(os.Stdout, nil) logger := slog.New(handler) logger.Info("Reading config") config, err := config.Load(".env") if err != nil { - logger.Error("Failed parsing config: %v", err) + logger.Error("Failed parsing config", "error", err) panic(err) } repo, err := repository.New(config.Database.URL()) if err != nil { - logger.Error(" Failed connecting to the database: $v", err) + logger.Error("Failed connecting to the database", "error", err) panic(err) } diff --git a/go.mod b/go.mod index a3f4fe4..45ecd7d 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,6 @@ require ( github.com/jackc/pgx/v4 v4.17.2 github.com/joho/godotenv v1.4.0 github.com/kelseyhightower/envconfig v1.4.0 - golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 ) require ( diff --git a/go.sum b/go.sum index 4a78c58..207ef6e 100644 --- a/go.sum +++ b/go.sum @@ -138,8 +138,6 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o= -golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= diff --git a/internal/core/operations.go b/internal/core/operations.go index d0bcfd1..40cd866 100644 --- a/internal/core/operations.go +++ b/internal/core/operations.go @@ -5,80 +5,73 @@ import "context" // CreateEvent coantains the business logic to create new events on the service, // calling the repository to actually store the new event. func (s service) CreateEvent(ctx context.Context, e Event) (*Event, error) { - s.logger.Info("Creating event with the following parameters: %v", e) - - if error := e.Validate(); error != nil { - return nil, error + if err := e.Validate(); err != nil { + s.logger.Error("Validation error", "error", err) + return nil, err } event, err := s.repo.CreateEvent(ctx, e) if err != nil { - error := NewError("Failed creating event: %v", ErrorUnknown) - s.logger.Error(error.msg, error) + error := NewError("Failed creating event", ErrorUnknown) + s.logger.Error(error.msg, "error", error) return nil, error } - s.logger.Info("Succesfully created the event") return event, nil } // GetEvent contains the business logic to read event details, // calling the repository to get the relevant payload. func (s service) GetEvent(ctx context.Context, id int64) (*Event, error) { - s.logger.Info("Getting event with ID: %s", id) if id == 0 { error := NewError("Invalid event ID: 0", ErrorInvalidArgument) - s.logger.Error(error.msg, error) + s.logger.Error(error.msg, "error", error) return nil, error } event, err := s.repo.GetEvent(ctx, id) if err != nil { error := NewError("Event not found", ErrorNotFound) - s.logger.Error(error.msg, error) + s.logger.Error(error.msg, "error", error) return nil, error } - s.logger.Info("Succesfully found the event: %v", event) return event, nil } // UpdateEvent contains the business logic to update events, // from the service, calling the repository to store the updated event. func (s service) UpdateEvent(ctx context.Context, e Event) (*Event, error) { - s.logger.Info("Updating event with the following parameters: %v", e) - if error := e.Validate(); error != nil { - return nil, error + if err := e.Validate(); err != nil { + s.logger.Error("Validation error", "error", err) + return nil, err } event, err := s.repo.UpdateEvent(ctx, e) if err != nil { - error := NewError("Failed Updating event: %v", ErrorUnknown) - s.logger.Error(error.msg, error) + error := NewError("Failed Updating event", ErrorUnknown) + s.logger.Error(error.msg, "error", error) return nil, error } - s.logger.Info("Succesfully updated the event") return event, nil } // DeleteEvent contains the business logic for the deletion of the event // from the service, calling the repository to actually delete it. func (s service) DeleteEvent(ctx context.Context, id int64) error { - s.logger.Info("Deleting event with ID: %s", id) if id == 0 { error := NewError("Invalid event ID: 0", ErrorInvalidArgument) - s.logger.Error(error.msg, error) + s.logger.Error(error.msg, "error", error) return error } err := s.repo.DeleteEvent(ctx, id) if err != nil { error := NewError("Event not found", ErrorNotFound) - s.logger.Error(error.msg, error) + s.logger.Error(error.msg, "error", error) return error } - s.logger.Info("Succesfully deleted the event") return nil } diff --git a/internal/core/service.go b/internal/core/service.go index 5568170..15e954b 100644 --- a/internal/core/service.go +++ b/internal/core/service.go @@ -3,7 +3,7 @@ package core import ( "context" - "golang.org/x/exp/slog" + "log/slog" ) // BastetService is the main usecase of the app, centered around event CRUD operations. diff --git a/internal/server/operations.go b/internal/server/operations.go index 3db1bb8..ce384c3 100644 --- a/internal/server/operations.go +++ b/internal/server/operations.go @@ -24,7 +24,6 @@ func (s server) CreateEvent(w http.ResponseWriter, r *http.Request) { renderErrorResponse(w, r, err) return } - s.logger.Info("Create event request received with body: %v", &event) e, err := s.service.CreateEvent(r.Context(), event.toCoreEvent()) if err != nil { @@ -33,7 +32,6 @@ func (s server) CreateEvent(w http.ResponseWriter, r *http.Request) { return } - s.logger.Info("Successfully created the event") renderResponse(w, e) } @@ -42,9 +40,8 @@ func (s server) CreateEvent(w http.ResponseWriter, r *http.Request) { // If unsuccessful, an error response will be sent. func (s server) GetEvent(w http.ResponseWriter, r *http.Request) { id, err := strconv.ParseInt(chi.URLParam(r, "event_id"), 10, 64) - s.logger.Info("Finding event for ID: %v", id) if err != nil { - s.logger.Error("Failed parsing the request") + s.logger.Error("Failed parsing the request, could not parse the event ID") renderErrorResponse(w, r, err) return } @@ -56,7 +53,6 @@ func (s server) GetEvent(w http.ResponseWriter, r *http.Request) { return } - s.logger.Info("Successfully found the event") renderResponse(w, e) } @@ -71,7 +67,6 @@ func (s server) UpdateEvent(w http.ResponseWriter, r *http.Request) { renderErrorResponse(w, r, err) return } - s.logger.Info("Update event request received with body: %v", &event) if event.ID == 0 { id, err := strconv.ParseInt(chi.URLParam(r, "event_id"), 10, 64) @@ -90,7 +85,6 @@ func (s server) UpdateEvent(w http.ResponseWriter, r *http.Request) { return } - s.logger.Info("Successfully updated the event") renderResponse(w, e) } @@ -99,9 +93,8 @@ func (s server) UpdateEvent(w http.ResponseWriter, r *http.Request) { // If unsuccessful, an error response will be sent. func (s server) DeleteEvent(w http.ResponseWriter, r *http.Request) { id, err := strconv.ParseInt(chi.URLParam(r, "event_id"), 10, 64) - s.logger.Info("Deleting event for ID: %v", id) if err != nil { - s.logger.Error("Failed parsing the request") + s.logger.Error("Failed parsing the request, could not parse the event ID") renderErrorResponse(w, r, err) return } @@ -113,6 +106,5 @@ func (s server) DeleteEvent(w http.ResponseWriter, r *http.Request) { return } - s.logger.Info("Successfully deleted the event") renderResponse(w, map[string]interface{}{}) } diff --git a/internal/server/server.go b/internal/server/server.go index b049015..33e1c2d 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -2,12 +2,12 @@ package server import ( "fmt" + "log/slog" "net/http" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" "github.com/nanchano/bastet/internal/core" - "golang.org/x/exp/slog" ) // server represents the HTTP layer of the app, requiring a server to act.