Switched From httprouter to chi

I believe all functionality works properly
This commit is contained in:
Annika Merris 2024-02-07 19:15:25 -05:00
parent c1231d487a
commit d4b2d5fefb
9 changed files with 77 additions and 78 deletions

2
.env
View file

@ -1,2 +1,2 @@
DB_CONNECTION_STRING=postgres://isl:development@localhost:5432/isl
HTTP_PORT=3000
HTTP_PORT=3001

View file

@ -6,42 +6,24 @@ import (
"net/http"
"strconv"
"forgejo.merr.is/annika/isl-api/Entities"
"forgejo.merr.is/annika/isl-api/Services"
"forgejo.merr.is/annika/isl-api/Types"
"github.com/julienschmidt/httprouter"
"github.com/go-chi/chi/v5"
)
// TODO: Figure out a better place to put this.
func MiddleCORS(next httprouter.Handle) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
w.Header().Set("Access-Control-Allow-Origin", "*")
next(w, r, ps)
}
}
type PowerItemController struct {
powerItemService *Services.PowerItemService
}
func NewPowerItemController(router *httprouter.Router, powerItemService *Services.PowerItemService) *PowerItemController {
func NewPowerItemController(powerItemService *Services.PowerItemService) *PowerItemController {
controller := &PowerItemController{
powerItemService: powerItemService,
}
controller.setPowerItemEndpoints(router, "/powerItem")
return controller
}
func (p *PowerItemController) setPowerItemEndpoints(router *httprouter.Router, prefix string) {
router.GET(fmt.Sprintf("%v", prefix), MiddleCORS(p.getAll))
router.GET(fmt.Sprintf("%v/asMap", prefix), MiddleCORS(p.getAllAsMap))
router.GET(fmt.Sprintf("%v/byType/:type", prefix), MiddleCORS(p.getAllByType))
router.GET(fmt.Sprintf("%v/byType/:type/asMap", prefix), MiddleCORS(p.getAllByTypeAsMap))
router.POST(fmt.Sprintf("%v", prefix), MiddleCORS(p.add))
router.POST(fmt.Sprintf("%v/multiple", prefix), MiddleCORS(p.addMultiple))
}
func (p *PowerItemController) add(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
var newItem Types.PowerItem
func (p *PowerItemController) Add(w http.ResponseWriter, r *http.Request) {
var newItem Entities.PowerItem
err := json.NewDecoder(r.Body).Decode(&newItem)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
@ -64,9 +46,9 @@ func (p *PowerItemController) add(w http.ResponseWriter, r *http.Request, ps htt
fmt.Fprint(w, string(returnValue))
}
func (p *PowerItemController) addMultiple(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
func (p *PowerItemController) AddMultiple(w http.ResponseWriter, r *http.Request) {
var itemType int32 = 3
var newItems map[string]Types.PowerItem
var newItems map[string]Entities.PowerItem
err := json.NewDecoder(r.Body).Decode(&newItems)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
@ -92,7 +74,7 @@ func (p *PowerItemController) addMultiple(w http.ResponseWriter, r *http.Request
fmt.Fprint(w, string(returnValue))
}
func (p *PowerItemController) getAll(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
func (p *PowerItemController) GetAll(w http.ResponseWriter, r *http.Request) {
result, err := p.powerItemService.GetAll()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
@ -109,14 +91,14 @@ func (p *PowerItemController) getAll(w http.ResponseWriter, r *http.Request, ps
fmt.Fprint(w, string(data))
}
func (p *PowerItemController) getAllAsMap(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
func (p *PowerItemController) GetAllAsMap(w http.ResponseWriter, r *http.Request) {
items, err := p.powerItemService.GetAll()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
resultMap := make(map[string]Types.PowerItem)
resultMap := make(map[string]Entities.PowerItem)
for _, curItem := range items {
uuid := fmt.Sprintf("%x-%x-%x-%x-%x", curItem.ID.Bytes[0:4], curItem.ID.Bytes[4:6], curItem.ID.Bytes[6:8], curItem.ID.Bytes[8:10], curItem.ID.Bytes[10:16])
resultMap[uuid] = curItem
@ -132,8 +114,8 @@ func (p *PowerItemController) getAllAsMap(w http.ResponseWriter, r *http.Request
fmt.Fprint(w, string(data))
}
func (p *PowerItemController) getAllByType(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
typeCode, err := strconv.Atoi(ps.ByName("type"))
func (p *PowerItemController) GetAllByType(w http.ResponseWriter, r *http.Request) {
typeCode, err := strconv.Atoi(chi.URLParam(r, "type"))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
@ -155,8 +137,8 @@ func (p *PowerItemController) getAllByType(w http.ResponseWriter, r *http.Reques
fmt.Fprint(w, string(data))
}
func (p *PowerItemController) getAllByTypeAsMap(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
typeCode, err := strconv.Atoi(ps.ByName("type"))
func (p *PowerItemController) GetAllByTypeAsMap(w http.ResponseWriter, r *http.Request) {
typeCode, err := strconv.Atoi(chi.URLParam(r, "type"))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
@ -168,7 +150,7 @@ func (p *PowerItemController) getAllByTypeAsMap(w http.ResponseWriter, r *http.R
return
}
resultMap := make(map[string]Types.PowerItem)
resultMap := make(map[string]Entities.PowerItem)
for _, curItem := range items {
uuid := fmt.Sprintf("%x-%x-%x-%x-%x", curItem.ID.Bytes[0:4], curItem.ID.Bytes[4:6], curItem.ID.Bytes[6:8], curItem.ID.Bytes[8:10], curItem.ID.Bytes[10:16])
resultMap[uuid] = curItem

View file

@ -1,4 +1,4 @@
package Types
package Entities
import (
"forgejo.merr.is/annika/isl-api/sql/powerItem"

19
Routes/PowerItemRoutes.go Normal file
View file

@ -0,0 +1,19 @@
package routes
import (
"forgejo.merr.is/annika/isl-api/Controllers"
"github.com/go-chi/chi/v5"
)
func SetupPowerItemRoutes(c Controllers.PowerItemController) *chi.Mux {
r := chi.NewRouter()
r.Get("/", c.GetAll)
r.Get("/asMap", c.GetAllAsMap)
r.Get("/byType/{type:[1-3]}", c.GetAllByType)
r.Get("/byType/{type:[1-3]}/asMap", c.GetAllByTypeAsMap)
r.Post("/", c.Add)
r.Post("/multiple", c.AddMultiple)
return r
}

View file

@ -3,7 +3,7 @@ package Services
import (
"context"
"forgejo.merr.is/annika/isl-api/Types"
"forgejo.merr.is/annika/isl-api/Entities"
"forgejo.merr.is/annika/isl-api/sql/powerItem"
"github.com/jackc/pgtype"
)
@ -20,31 +20,31 @@ func NewPowerItemService(querier *powerItem.DBQuerier) *PowerItemService {
}
}
func (p *PowerItemService) GetAll() ([]Types.PowerItem, error) {
func (p *PowerItemService) GetAll() ([]Entities.PowerItem, error) {
rows, err := p.querier.GetAllItems(p.context)
if err != nil {
return []Types.PowerItem{}, err
return []Entities.PowerItem{}, err
}
var powerItems []Types.PowerItem
var powerItems []Entities.PowerItem
for _, sqlItem := range rows {
powerItems = append(powerItems, Types.FromGetAllItemsRow(sqlItem))
powerItems = append(powerItems, Entities.FromGetAllItemsRow(sqlItem))
}
return powerItems, nil
}
func (p *PowerItemService) GetAllByType(itemType int) ([]Types.PowerItem, error) {
func (p *PowerItemService) GetAllByType(itemType int) ([]Entities.PowerItem, error) {
rows, err := p.querier.GetAllByType(p.context, int32(itemType))
if err != nil {
return []Types.PowerItem{}, err
return []Entities.PowerItem{}, err
}
var powerItems []Types.PowerItem
var powerItems []Entities.PowerItem
for _, sqlItem := range rows {
powerItems = append(powerItems, Types.FromGetAllItemsByTypeRow(sqlItem))
powerItems = append(powerItems, Entities.FromGetAllItemsByTypeRow(sqlItem))
}
return powerItems, nil
}
func (p *PowerItemService) Add(newItem Types.PowerItem) (Types.PowerItem, error) {
func (p *PowerItemService) Add(newItem Entities.PowerItem) (Entities.PowerItem, error) {
sqlItem := powerItem.AddNewItemWithIDParams{
ID: newItem.ID,
ItemType: newItem.ItemType,
@ -59,14 +59,14 @@ func (p *PowerItemService) Add(newItem Types.PowerItem) (Types.PowerItem, error)
}
row, err := p.querier.AddNewItemWithID(p.context, powerItem.AddNewItemWithIDParams(sqlItem))
if err != nil {
return Types.PowerItem{}, err
return Entities.PowerItem{}, err
}
return Types.FromAddNewItemWithIDParams(row), nil
return Entities.FromAddNewItemWithIDParams(row), nil
}
func (p *PowerItemService) AddMultipile(newItems map[string]Types.PowerItem, itemType int32) ([]Types.PowerItem, []error) {
func (p *PowerItemService) AddMultipile(newItems map[string]Entities.PowerItem, itemType int32) ([]Entities.PowerItem, []error) {
var errors []error
var addedItems []Types.PowerItem
var addedItems []Entities.PowerItem
for key, value := range newItems {
id := pgtype.UUID{}
id.Set(key)
@ -87,7 +87,7 @@ func (p *PowerItemService) AddMultipile(newItems map[string]Types.PowerItem, ite
errors = append(errors, err)
continue
}
addedItems = append(addedItems, Types.FromAddNewItemWithIDParams(row))
addedItems = append(addedItems, Entities.FromAddNewItemWithIDParams(row))
}
return addedItems, errors
}

View file

@ -9,7 +9,7 @@ services:
- ISL_API_DB_CONNECTION_STRING=postgres://isl:development@db:5432/isl
- ISL_API_HTTP_PORT=3000
ports:
- 3080:3000
- 3000:3000
db:
image: postgres
restart: always
@ -26,4 +26,4 @@ services:
image: adminer
restart: always
ports:
- 8080:8080
- 8081:8080

5
go.mod
View file

@ -11,6 +11,8 @@ require (
require (
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-chi/chi/v5 v5.0.11 // indirect
github.com/go-chi/cors v1.2.1 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgio v1.0.0 // indirect
@ -30,10 +32,11 @@ require (
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.18.2 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/zitadel/zitadel-go/v3 v3.0.0-next.2 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
golang.org/x/crypto v0.16.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
golang.org/x/exp v0.0.0-20231219180239-dc181d75b848 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect

8
go.sum
View file

@ -11,6 +11,10 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/go-chi/chi/v5 v5.0.11 h1:BnpYbFZ3T3S1WMpD79r7R5ThWX40TaFB7L31Y8xqSwA=
github.com/go-chi/chi/v5 v5.0.11/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
@ -147,6 +151,8 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
github.com/zitadel/zitadel-go/v3 v3.0.0-next.2 h1:w0lnLvijwQwkrUEA74loenNR9udRAaq6rccjlMSA+4U=
github.com/zitadel/zitadel-go/v3 v3.0.0-next.2/go.mod h1:SY9IZuDw/766mwEobCX7JNwXawIQxVseo679JG1U0c0=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
@ -178,6 +184,8 @@ golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
golang.org/x/exp v0.0.0-20231219180239-dc181d75b848 h1:+iq7lrkxmFNBM7xx+Rae2W6uyPfhPeDWD+n+JgppptE=
golang.org/x/exp v0.0.0-20231219180239-dc181d75b848/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
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=

37
main.go
View file

@ -7,10 +7,12 @@ import (
"net/http"
"forgejo.merr.is/annika/isl-api/Controllers"
routes "forgejo.merr.is/annika/isl-api/Routes"
"forgejo.merr.is/annika/isl-api/Services"
"forgejo.merr.is/annika/isl-api/sql/powerItem"
"github.com/go-chi/chi/v5"
"github.com/go-chi/cors"
"github.com/jackc/pgx/v4/pgxpool"
"github.com/julienschmidt/httprouter"
"github.com/spf13/viper"
)
@ -24,8 +26,6 @@ func main() {
deps := dependencies{}
deps.initializeDependencies()
deps.router.HandlerFunc("GET", "/", index)
fmt.Printf("Preparing to listen on `:%v`\n", conf.HttpPort)
err := http.ListenAndServe(fmt.Sprintf(":%v", conf.HttpPort), deps.router)
log.Fatal(err)
@ -49,7 +49,7 @@ func setupConfig() {
}
type dependencies struct {
router *httprouter.Router
router *chi.Mux
postgresConnection *pgxpool.Pool
context context.Context
powerItemQuerier *powerItem.DBQuerier
@ -60,15 +60,12 @@ type dependencies struct {
func (d *dependencies) initializeDependencies() error {
var err error
d.router = httprouter.New()
d.router.GlobalOPTIONS = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Access-Control-Request-Method") != "" {
header := w.Header()
header.Set("Access-Control-Allow-Methods", header.Get("Allow"))
header.Set("Access-Control-Allow-Headers", "Cache-Control, Expires, Pragma")
header.Set("Access-Control-Allow-Origin", "*")
}
})
d.router = chi.NewRouter()
d.router.Use(cors.Handler(cors.Options{
AllowedOrigins: []string{"*"},
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowedHeaders: []string{"Cache-Control", "Expires", "Pragma"},
}))
d.context = context.Background()
d.postgresConnection, err = pgxpool.Connect(d.context, conf.ConnectionString)
if err != nil {
@ -76,17 +73,7 @@ func (d *dependencies) initializeDependencies() error {
}
d.powerItemQuerier = powerItem.NewQuerier(d.postgresConnection)
d.powerItemService = Services.NewPowerItemService(d.powerItemQuerier)
d.powerItemController = Controllers.NewPowerItemController(d.router, d.powerItemService)
d.powerItemController = Controllers.NewPowerItemController(d.powerItemService)
d.router.Mount("/powerItems", routes.SetupPowerItemRoutes(*d.powerItemController))
return nil
}
func MiddleCORS(next httprouter.Handle) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
w.Header().Set("Access-Control-Allow-Origin", "*")
next(w, r, ps)
}
}
func index(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Index")
}