This commit is contained in:
Bronku 2025-08-06 21:03:38 +02:00
parent 4df52360e8
commit cdf42b7ff3
4 changed files with 99 additions and 6 deletions

View file

@ -4,3 +4,4 @@ File = "foo.db"
[Server] [Server]
Addr = ":8080" Addr = ":8080"
ReadHeaderTimeout = "3s" ReadHeaderTimeout = "3s"
RequestTimeout = "10s"

2
go.mod
View file

@ -12,6 +12,8 @@ require (
) )
require ( require (
github.com/go-chi/chi v1.5.5
github.com/go-chi/chi/v5 v5.2.2
gorm.io/driver/sqlite v1.6.0 gorm.io/driver/sqlite v1.6.0
gorm.io/gorm v1.30.0 gorm.io/gorm v1.30.0
) )

4
go.sum
View file

@ -1,5 +1,9 @@
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/go-chi/chi v1.5.5 h1:vOB/HbEMt9QqBqErz07QehcOKHaWFtuj87tTDVz2qXE=
github.com/go-chi/chi v1.5.5/go.mod h1:C9JqLr3tIYjDOZpzn+BCuxY8z8vmca43EeMgyZt7irw=
github.com/go-chi/chi/v5 v5.2.2 h1:CMwsvRVTbXVytCk1Wd72Zy1LAsAh9GxMmSNWLHCG618=
github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=

98
main.go
View file

@ -1,14 +1,22 @@
package main package main
import ( import (
"context"
_ "embed" _ "embed"
"errors"
"fmt"
"log" "log"
"net/http" "net/http"
"strconv"
"time" "time"
"github.com/Bronku/iroon/server" "github.com/Bronku/iroon/models"
"github.com/Bronku/iroon/store" "github.com/Bronku/iroon/store"
"github.com/BurntSushi/toml" "github.com/BurntSushi/toml"
"github.com/go-chi/chi/middleware"
"github.com/go-chi/chi/v5"
"gorm.io/gorm"
"gorm.io/gorm/clause"
) )
type config struct { type config struct {
@ -19,12 +27,18 @@ type config struct {
Server struct { Server struct {
Addr string Addr string
ReadHeaderTimeout time.Duration ReadHeaderTimeout time.Duration
RequestTimeout time.Duration
} }
} }
//go:embed config.default.toml //go:embed config.default.toml
var defaultConfig string var defaultConfig string
type contextKey string
const dbContextKey = contextKey("db")
const orderContextKey = contextKey("order")
func main() { func main() {
// load config // load config
var conf config var conf config
@ -43,14 +57,32 @@ func main() {
log.Panic(err) log.Panic(err)
} }
// load server r := chi.NewRouter()
h := server.New(db) r.Use(middleware.RequestID)
var handler http.Handler = h r.Use(middleware.RealIP)
log.Println("starting server") r.Use(middleware.Logger)
r.Use(middleware.Recoverer)
r.Use(middleware.Timeout(conf.Server.RequestTimeout))
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("welcome"))
})
r.Route("/orders", func(r chi.Router) {
r.Use(middleware.WithValue(dbContextKey, db))
r.Route("/{orderID}", func(r chi.Router) {
r.Use(OrderCtx) // Load the *Article on the request context
r.Get("/", getOrder)
// r.Get("/", GetArticle) // GET /articles/123
// r.Put("/", UpdateArticle) // PUT /articles/123
// r.Delete("/", DeleteArticle) // DELETE /articles/123
})
})
// start server // start server
server := &http.Server{ server := &http.Server{
Handler: handler, Handler: r,
Addr: conf.Server.Addr, Addr: conf.Server.Addr,
ReadHeaderTimeout: conf.Server.ReadHeaderTimeout, ReadHeaderTimeout: conf.Server.ReadHeaderTimeout,
} }
@ -59,3 +91,57 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
} }
// can't get item from context, please include it before registering route
var errNoContextValue = errors.New("no value from context")
func OrderCtx(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
db := r.Context().Value(dbContextKey).(*gorm.DB)
if db == nil {
panic(errNoContextValue)
}
var order *models.Order
var err error
orderID, err := strconv.Atoi(chi.URLParam(r, "orderID"))
if err != nil {
w.Write([]byte("url not found"))
return
}
err = db.Preload("OrderItems.Product").Preload(clause.Associations).Find(&order, orderID).Error
if err != nil {
w.Write([]byte("item not found"))
return
}
ctx := context.WithValue(r.Context(), orderContextKey, order)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
func getOrder(w http.ResponseWriter, r *http.Request) {
var db *gorm.DB
var catalogue []models.Product
var order *models.Order
var err error
db = r.Context().Value(dbContextKey).(*gorm.DB)
if db == nil {
panic(errNoContextValue)
}
err = db.Find(&catalogue).Error
if err != nil {
w.Write([]byte("no catalogue"))
return
}
order = r.Context().Value(orderContextKey).(*models.Order)
if order == nil {
panic(errNoContextValue)
}
fmt.Fprint(w, "order: ", order, "\ncatalogue: ", catalogue)
}