Skip to content

Instantly share code, notes, and snippets.

@winniethemu
Created January 15, 2026 05:57
Show Gist options
  • Select an option

  • Save winniethemu/7e51029e97751c33fb964c5d9e514e34 to your computer and use it in GitHub Desktop.

Select an option

Save winniethemu/7e51029e97751c33fb964c5d9e514e34 to your computer and use it in GitHub Desktop.
Concurrent Shopping Cart
package main
import (
"log/slog"
"os"
)
func main() {
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
app := &App{
cart: make(map[int]Value),
logger: logger,
version: 0,
}
err := app.serve()
if err != nil {
logger.Error(err.Error())
os.Exit(1)
}
}
package main
import (
"encoding/json"
"log/slog"
"net/http"
)
type App struct {
cart map[int]Value
logger *slog.Logger
version int
}
type Value []string
type Request struct {
ClientID int `json:"clientID,omitempty"`
Items []string `json:"items,omitempty"`
Version int `json:"version,omitempty"`
}
type Response struct {
Values map[int]Value `json:"values,omitempty"`
Version int `json:"version,omitempty"`
}
func (app *App) serve() error {
http.HandleFunc("GET /cart", app.handleGet)
http.HandleFunc("PUT /cart", app.handlePut)
app.logger.Info("starting server on port 3000...")
err := http.ListenAndServe(":3000", nil)
if err != nil {
return err
}
app.logger.Info("stopped server.")
return nil
}
func (app *App) handleGet(w http.ResponseWriter, r *http.Request) {
app.logger.Info("handling GET...")
res := Response{
Values: app.cart,
Version: app.version,
}
writeJSON(w, 200, res)
}
func (app *App) handlePut(w http.ResponseWriter, r *http.Request) {
app.logger.Info("handling PUT...")
var req Request
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
w.WriteHeader(400)
return
}
if _, found := app.cart[req.ClientID]; found {
if req.Version < app.version {
app.cart[req.ClientID] = req.Items
app.version++
}
} else {
if len(app.cart) == 0 {
app.version = 1
} else {
app.version++
}
app.cart[req.ClientID] = req.Items
}
res := Response{
Values: app.cart,
Version: app.version,
}
writeJSON(w, 200, res)
}
func writeJSON(w http.ResponseWriter, status int, data any) {
bytes, err := json.Marshal(data)
if err != nil {
w.WriteHeader(500)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
w.Write(bytes)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment