Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
a0f65394d4
|
|||
|
7a37224487
|
|||
|
b98b184a32
|
|||
|
dace105a9a
|
2
go.mod
2
go.mod
@@ -4,7 +4,7 @@ go 1.24.0
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
git.itzana.me/StrafesNET/dev-service v0.0.0-20250628022558-4cf59e46f9f1
|
git.itzana.me/StrafesNET/dev-service v0.0.0-20250628022558-4cf59e46f9f1
|
||||||
git.itzana.me/strafesnet/go-grpc v0.0.0-20250628021738-df0a4ad40969
|
git.itzana.me/strafesnet/go-grpc v0.0.0-20250724030029-845bea991815
|
||||||
github.com/gin-gonic/gin v1.10.1
|
github.com/gin-gonic/gin v1.10.1
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
github.com/swaggo/files v1.0.1
|
github.com/swaggo/files v1.0.1
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -2,8 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
|
|||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
git.itzana.me/StrafesNET/dev-service v0.0.0-20250628022558-4cf59e46f9f1 h1:Ndpa4d93gCQrW5pm64u9IRaDJTfu7fKfLqm8ctzML1o=
|
git.itzana.me/StrafesNET/dev-service v0.0.0-20250628022558-4cf59e46f9f1 h1:Ndpa4d93gCQrW5pm64u9IRaDJTfu7fKfLqm8ctzML1o=
|
||||||
git.itzana.me/StrafesNET/dev-service v0.0.0-20250628022558-4cf59e46f9f1/go.mod h1:KJal0K++M6HEzSry6JJ2iDPZtOQn5zSstNlDbU3X4Jg=
|
git.itzana.me/StrafesNET/dev-service v0.0.0-20250628022558-4cf59e46f9f1/go.mod h1:KJal0K++M6HEzSry6JJ2iDPZtOQn5zSstNlDbU3X4Jg=
|
||||||
git.itzana.me/strafesnet/go-grpc v0.0.0-20250628021738-df0a4ad40969 h1:bGfsRi9WrklI5cwvfvI/jJAGa3PQgJVNAzseFBW56mY=
|
git.itzana.me/strafesnet/go-grpc v0.0.0-20250724030029-845bea991815 h1:hkuOnehphRXUq/2z2UYgoqTq5MJj1GsWfshyc7bXda8=
|
||||||
git.itzana.me/strafesnet/go-grpc v0.0.0-20250628021738-df0a4ad40969/go.mod h1:X7XTRUScRkBWq8q8bplbeso105RPDlnY7J6Wy1IwBMs=
|
git.itzana.me/strafesnet/go-grpc v0.0.0-20250724030029-845bea991815/go.mod h1:X7XTRUScRkBWq8q8bplbeso105RPDlnY7J6Wy1IwBMs=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||||
|
|||||||
@@ -5,10 +5,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MapFilter struct {
|
|
||||||
GameID *int32 `json:"game_id" form:"game_id"`
|
|
||||||
} // @name MapFilter
|
|
||||||
|
|
||||||
type Map struct {
|
type Map struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
DisplayName string `json:"display_name"`
|
DisplayName string `json:"display_name"`
|
||||||
|
|||||||
40
pkg/api/dto/map_extended.go
Normal file
40
pkg/api/dto/map_extended.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package dto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.itzana.me/strafesnet/go-grpc/maps_extended"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MapExtendedFilter struct {
|
||||||
|
GameID *uint32 `json:"game_id" form:"game_id"`
|
||||||
|
} // @name MapFilter
|
||||||
|
|
||||||
|
type MapExtended struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
DisplayName string `json:"display_name"`
|
||||||
|
Creator string `json:"creator"`
|
||||||
|
GameID uint32 `json:"game_id"`
|
||||||
|
Date time.Time `json:"date"`
|
||||||
|
CreatedAt time.Time `json:created_at`
|
||||||
|
UpdatedAt time.Time `json:updated_at`
|
||||||
|
Submitter uint64 `json:submitter`
|
||||||
|
Thumbnail uint64 `json:thumbnail`
|
||||||
|
AssetVersion uint64 `json:asset_version`
|
||||||
|
LoadCount uint32 `json:load_count`
|
||||||
|
Modes uint32 `json:modes`
|
||||||
|
} // @name Map
|
||||||
|
|
||||||
|
// FromGRPC converts a maps.MapResponse protobuf message to a Map domain object
|
||||||
|
func (m *MapExtended) FromGRPC(resp *maps_extended.MapResponse) *MapExtended {
|
||||||
|
if resp == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
m.ID = resp.ID
|
||||||
|
m.DisplayName = resp.DisplayName
|
||||||
|
m.Creator = resp.Creator
|
||||||
|
m.Date = time.Unix(resp.Date, 0)
|
||||||
|
m.GameID = resp.GameID
|
||||||
|
|
||||||
|
return m
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ const (
|
|||||||
// Handler is a base handler that provides common functionality for all HTTP handlers.
|
// Handler is a base handler that provides common functionality for all HTTP handlers.
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
dataClient *grpc.ClientConn
|
dataClient *grpc.ClientConn
|
||||||
|
mapsClient *grpc.ClientConn
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandlerOption defines a functional option for configuring a Handler
|
// HandlerOption defines a functional option for configuring a Handler
|
||||||
@@ -26,6 +27,13 @@ func WithDataClient(dataClient *grpc.ClientConn) HandlerOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithMapsClient sets the maps client for the Handler
|
||||||
|
func WithMapsClient(mapsClient *grpc.ClientConn) HandlerOption {
|
||||||
|
return func(h *Handler) {
|
||||||
|
h.mapsClient = mapsClient
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NewHandler creates a new Handler with the provided options.
|
// NewHandler creates a new Handler with the provided options.
|
||||||
// It requires both a datastore and an authentication service to function properly.
|
// It requires both a datastore and an authentication service to function properly.
|
||||||
func NewHandler(options ...HandlerOption) (*Handler, error) {
|
func NewHandler(options ...HandlerOption) (*Handler, error) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.itzana.me/strafesnet/go-grpc/maps"
|
"git.itzana.me/strafesnet/go-grpc/maps_extended"
|
||||||
"git.itzana.me/strafesnet/public-api/pkg/api/dto"
|
"git.itzana.me/strafesnet/public-api/pkg/api/dto"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
@@ -49,7 +49,7 @@ func (h *MapHandler) Get(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call the gRPC service
|
// Call the gRPC service
|
||||||
mapData, err := maps.NewMapsServiceClient(h.dataClient).Get(ctx, &maps.IdMessage{
|
mapData, err := maps_extended.NewMapsServiceClient(h.mapsClient).Get(ctx, &maps_extended.MapId{
|
||||||
ID: mapID,
|
ID: mapID,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -72,11 +72,11 @@ func (h *MapHandler) Get(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert gRPC MapResponse object to dto.Map object
|
// Convert gRPC MapResponse object to dto.Map object
|
||||||
var mapDto dto.Map
|
var mapDto dto.MapExtended
|
||||||
result := mapDto.FromGRPC(mapData)
|
result := mapDto.FromGRPC(mapData)
|
||||||
|
|
||||||
// Return the map data
|
// Return the map data
|
||||||
ctx.JSON(http.StatusOK, dto.Response[dto.Map]{
|
ctx.JSON(http.StatusOK, dto.Response[dto.MapExtended]{
|
||||||
Data: *result,
|
Data: *result,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ func (h *MapHandler) List(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get list filter
|
// Get list filter
|
||||||
var filter dto.MapFilter
|
var filter dto.MapExtendedFilter
|
||||||
if err := ctx.ShouldBindQuery(&filter); err != nil {
|
if err := ctx.ShouldBindQuery(&filter); err != nil {
|
||||||
ctx.JSON(http.StatusBadRequest, dto.Error{
|
ctx.JSON(http.StatusBadRequest, dto.Error{
|
||||||
Error: err.Error(),
|
Error: err.Error(),
|
||||||
@@ -116,13 +116,13 @@ func (h *MapHandler) List(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call the gRPC service
|
// Call the gRPC service
|
||||||
mapList, err := maps.NewMapsServiceClient(h.dataClient).List(ctx, &maps.ListRequest{
|
mapList, err := maps_extended.NewMapsServiceClient(h.mapsClient).List(ctx, &maps_extended.ListRequest{
|
||||||
Filter: &maps.MapFilter{
|
Filter: &maps_extended.MapFilter{
|
||||||
GameID: filter.GameID,
|
GameID: filter.GameID,
|
||||||
},
|
},
|
||||||
Page: &maps.Pagination{
|
Page: &maps_extended.Pagination{
|
||||||
Size: int32(query.PageSize),
|
Size: uint32(query.PageSize),
|
||||||
Number: int32(query.PageNumber),
|
Number: uint32(query.PageNumber),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -136,14 +136,14 @@ func (h *MapHandler) List(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert gRPC MapResponse objects to dto.Map objects
|
// Convert gRPC MapResponse objects to dto.Map objects
|
||||||
dtoMaps := make([]dto.Map, len(mapList.Maps))
|
dtoMaps := make([]dto.MapExtended, len(mapList.Maps))
|
||||||
for i, m := range mapList.Maps {
|
for i, m := range mapList.Maps {
|
||||||
var mapDto dto.Map
|
var mapDto dto.MapExtended
|
||||||
dtoMaps[i] = *mapDto.FromGRPC(m)
|
dtoMaps[i] = *mapDto.FromGRPC(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the paged response
|
// Return the paged response
|
||||||
ctx.JSON(http.StatusOK, dto.PagedResponse[dto.Map]{
|
ctx.JSON(http.StatusOK, dto.PagedResponse[dto.MapExtended]{
|
||||||
Data: dtoMaps,
|
Data: dtoMaps,
|
||||||
Pagination: dto.Pagination{
|
Pagination: dto.Pagination{
|
||||||
Page: query.PageNumber,
|
Page: query.PageNumber,
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ type RouterConfig struct {
|
|||||||
port int
|
port int
|
||||||
devClient *grpc.ClientConn
|
devClient *grpc.ClientConn
|
||||||
dataClient *grpc.ClientConn
|
dataClient *grpc.ClientConn
|
||||||
|
mapsClient *grpc.ClientConn
|
||||||
context *cli.Context
|
context *cli.Context
|
||||||
shutdownTimeout time.Duration
|
shutdownTimeout time.Duration
|
||||||
}
|
}
|
||||||
@@ -57,6 +58,13 @@ func WithDataClient(conn *grpc.ClientConn) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithMapsClient sets the maps gRPC client
|
||||||
|
func WithMapsClient(conn *grpc.ClientConn) Option {
|
||||||
|
return func(cfg *RouterConfig) {
|
||||||
|
cfg.mapsClient = conn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithShutdownTimeout sets the graceful shutdown timeout
|
// WithShutdownTimeout sets the graceful shutdown timeout
|
||||||
func WithShutdownTimeout(timeout time.Duration) Option {
|
func WithShutdownTimeout(timeout time.Duration) Option {
|
||||||
return func(cfg *RouterConfig) {
|
return func(cfg *RouterConfig) {
|
||||||
@@ -72,6 +80,7 @@ func setupRoutes(cfg *RouterConfig) (*gin.Engine, error) {
|
|||||||
|
|
||||||
handlerOptions := []handlers.HandlerOption{
|
handlerOptions := []handlers.HandlerOption{
|
||||||
handlers.WithDataClient(cfg.dataClient),
|
handlers.WithDataClient(cfg.dataClient),
|
||||||
|
handlers.WithMapsClient(cfg.mapsClient),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Times handler
|
// Times handler
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ func NewApiCommand() *cli.Command {
|
|||||||
EnvVars: []string{"DATA_RPC_HOST"},
|
EnvVars: []string{"DATA_RPC_HOST"},
|
||||||
Value: "data-service:9000",
|
Value: "data-service:9000",
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "maps-rpc-host",
|
||||||
|
Usage: "Host of maps rpc",
|
||||||
|
EnvVars: []string{"MAPS_RPC_HOST"},
|
||||||
|
Value: "maptest-api:8081",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -48,10 +54,17 @@ func runAPI(ctx *cli.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Maps service client
|
||||||
|
mapsConn, err := grpc.Dial(ctx.String("maps-rpc-host"), grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return api.NewRouter(
|
return api.NewRouter(
|
||||||
api.WithContext(ctx),
|
api.WithContext(ctx),
|
||||||
api.WithPort(ctx.Int("port")),
|
api.WithPort(ctx.Int("port")),
|
||||||
api.WithDevClient(devConn),
|
api.WithDevClient(devConn),
|
||||||
api.WithDataClient(dataConn),
|
api.WithDataClient(dataConn),
|
||||||
|
api.WithMapsClient(mapsConn),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user