GlobalWebIndex Engineering Challenge#46
Conversation
…EADME and Postman collection
lkslts64
left a comment
There was a problem hiding this comment.
Hey @SpBalis , thanks for submitting the engineering challenge. We appreciate your effort!
Your project has a clean layered architecture, decent RESTful API design and nice features such as pagination and graceful server shutdown 💯
Furthermore, thanks for adding the Postman collection.
Could you please have a look at the comments I left below? Thanks again!
| Good luck, potential colleague! | ||
| --- | ||
|
|
||
| ## How to run |
There was a problem hiding this comment.
When trying to run the app through Docker, I noticed that many endpoints return 500 due to the database not running. What setup did you intend for the DB, and how should it be started? In a production-ready app, how would you handle the app's behaviour when the DB is unavailable?
There was a problem hiding this comment.
The app expects a running local Postgres instance with the schema initialized from migrations/001_init.sql.
When running via Docker, you can point to a host Postgres using:
docker run --rm -p 8080:8080
-e DATABASE_URL="postgres://gwi_user:gwi_pass@host.docker.internal:5432/gwi?sslmode=disable"
platform-go-challenge:latest
In a production-ready setup, I’d add a readiness check so the service doesn’t accept traffic until the DB connection succeeds, and keep the current fail-fast on startup if DATABASE_URL is missing or invalid, as it already behaves when running locally.
| r.Post("/users", h.CreateUser) | ||
| r.Get("/users/{id}", h.GetUser) | ||
| r.Get("/users", h.ListUsers) | ||
|
|
||
| //Handle favourites | ||
| r.Get("/users/{id}/favourites", h.List) | ||
| r.Post("/users/{id}/favourites", h.Add) | ||
| r.Delete("/users/{id}/favourites/{assetId}", h.Remove) | ||
| r.Patch("/users/{id}/favourites/{assetId}", h.EditDesc) | ||
| r.Delete("/users/{id}/favourites", h.ClearAll) |
There was a problem hiding this comment.
Can you briefly explain which middleware you would add to your HTTP handlers?
In general, how would you enable sufficient observability for debugging and production monitoring?
There was a problem hiding this comment.
I’d add a few middleware components to improve resilience and maintainability:
- Α recovery handler to avoid panics crashing the process,
- Structured request logging with request IDs for easy debugging,
- Per-request timeouts, validation, and optional CORS/auth layers.
For observability, I’d include:
- Structured logs with correlation IDs,
- Basic metrics (requests count, latency, DB connections),
- Simple health endpoints (/healthz and /readyz),
| "github.com/go-chi/chi/v5" | ||
| ) | ||
|
|
||
| type Handler struct { |
There was a problem hiding this comment.
If you were to include tests, what kind of tests would you add for this specific project?
Which components would you prioritize testing first, and how would you structure tests around the DB layer?
There was a problem hiding this comment.
For this kind of project, I’d start by testing the service layer, since that’s where most of the business logic lives.
Τhings like adding, editing, or removing favourites, and making sure we handle duplicates or validation correctly.
These can be simple unit tests using an in-memory or fake repository.
Next, I’d add a few HTTP handler tests using Go’s httptest package to make sure the endpoints return the right status codes, JSON responses, and pagination results.
Finally, I’d include some integration tests that run against a real Postgres instance (probably in Docker).
Those would apply the migrations and check that inserts, updates, constraints, and pagination all work as expected.
Each test would run in isolation, so the DB stays clean between runs.
Overall, I’d keep the DB tests small but meaningful and focus most of the coverage on the service layer for speed and clarity.
| COPY . . | ||
| RUN CGO_ENABLED=0 GOOS=linux go build -o platform-go-challenge ./cmd/server | ||
|
|
||
| FROM gcr.io/distroless/base-debian12 |
| log.Fatal("DATABASE_URL must be set") | ||
| } | ||
|
|
||
| db, err := repo.Open(cfg.DatabaseURL) |
There was a problem hiding this comment.
What are the reasons you opted for a relational SQL DB? Could you briefly explain why?
There was a problem hiding this comment.
I chose a relational database mainly because the data model fits well.
We have clear relationships between users, favourites, and assets.
Each favourite connects a user to an asset, which is a classic case for SQL with foreign keys and constraints.
Postgres also gives strong consistency guarantees and good support for structured data with JSONB, which lets me store the flexible “asset details” while keeping everything else normalized.
GWI platform-go-challenge (Go)
This challenge is designed to give you the opportunity to demonstrate your abilities as a software engineer and specifically your knowledge of the Go language.
data)