Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GraphQLのリゾルバを分割 #296

Merged
merged 10 commits into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions backend/cmd/di/di.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,24 @@ import (
)

func InitializeUserLoginController(cfg config.Config) gin_controller.UserLoginController {
uuidGenerator := uuid.NewUUIDGenerator()
mysqlConnector := mustGetWriteConnector(cfg)
mysqlUsersRepositoryConnector := mysqlconnector.NewMySQLRepositoryConnector(uuidGenerator, mysqlConnector)
jwtService := jwt.NewJWTGateway([]byte(cfg.SecretKey))
passwordHasher := hash.NewPasswordHasher(bcrypt.DefaultCost)
uc := usecase.NewUser(jwtService, passwordHasher, mysqlUsersRepositoryConnector)
uc := usecase.NewUser(jwtService, passwordHasher)
presenter := gin_presenter.NewJWTPresenter()
return gin_controller.NewUserLoginController(uc, presenter)
}

func InitializeUserRegisterController(cfg config.Config) gin_controller.UserRegisterController {
uuidGenerator := uuid.NewUUIDGenerator()
mysqlConnector := mustGetWriteConnector(cfg)
mysqlUsersRepositoryConnector := mysqlconnector.NewMySQLRepositoryConnector(uuidGenerator, mysqlConnector)
jwtService := jwt.NewJWTGateway([]byte(cfg.SecretKey))
passwordHasher := hash.NewPasswordHasher(bcrypt.DefaultCost)
uc := usecase.NewUser(jwtService, passwordHasher, mysqlUsersRepositoryConnector)
uc := usecase.NewUser(jwtService, passwordHasher)
presenter := gin_presenter.NewJWTPresenter()
return gin_controller.NewUserRegisterController(uc, presenter)
}

func InitializeDatabaseConnectionMiddleware(cfg config.Config) gin_controller.DatabaseConnectionMiddleware {
uuidGenerator := uuid.NewUUIDGenerator()
mysqlConnector := mustGetWriteConnector(cfg)
mysqlUsersRepositoryConnector := mysqlconnector.NewMySQLRepositoryConnector(uuidGenerator, mysqlConnector)
return gin_controller.NewDatabaseConnectionMiddleware(uuidGenerator, mysqlUsersRepositoryConnector)
}
30 changes: 20 additions & 10 deletions backend/cmd/di/gql.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,39 @@ import (

config "github.com/FlowingSPDG/get5loader/backend/cfg"
"github.com/FlowingSPDG/get5loader/backend/g5ctx"
mysqlconnector "github.com/FlowingSPDG/get5loader/backend/gateway/database/mysql/connector"
"github.com/FlowingSPDG/get5loader/backend/graph"
"github.com/FlowingSPDG/get5loader/backend/graph/dataloaders"
"github.com/FlowingSPDG/get5loader/backend/service/jwt"
hash "github.com/FlowingSPDG/get5loader/backend/service/password_hash"
"github.com/FlowingSPDG/get5loader/backend/service/uuid"
"github.com/FlowingSPDG/get5loader/backend/usecase"
)

func InitializeGraphQLHandler(cfg config.Config) gin.HandlerFunc {
// dependencies
uuidGenerator := uuid.NewUUIDGenerator()
jwtService := jwt.NewJWTGateway([]byte(cfg.SecretKey))
passwordHasher := hash.NewPasswordHasher(bcrypt.DefaultCost)
mysqlConnector := mustGetWriteConnector(cfg)
mysqlUsersRepositoryConnector := mysqlconnector.NewMySQLRepositoryConnector(uuidGenerator, mysqlConnector)

// usecases
gameServerUc := usecase.NewGameServer(mysqlUsersRepositoryConnector)
matchUc := usecase.NewMatch(mysqlUsersRepositoryConnector)
userUc := usecase.NewUser(jwtService, passwordHasher, mysqlUsersRepositoryConnector)
teamUc := usecase.NewTeam(mysqlUsersRepositoryConnector)
userUc := usecase.NewUser(jwtService, passwordHasher)
teamUc := usecase.NewTeam()
playerUc := usecase.NewPlayer()
gameServerUc := usecase.NewGameServer()
matchUc := usecase.NewMatch()
mapStatUc := usecase.NewMapStats()
playerStatUc := usecase.NewPlayerStat()

// dataloader
dl := dataloaders.NewLoaders(playerUc, matchUc, teamUc, mapStatUc, playerStatUc, gameServerUc)

// handler
h := handler.NewDefaultServer(graph.NewExecutableSchema(graph.Config{Resolvers: &graph.Resolver{
GameServerUsecase: gameServerUc,
MatchUsecase: matchUc,
UserUsecase: userUc,
MatchUsecase: matchUc,
MapstatUsecase: mapStatUc,
TeamUsecase: teamUc,
PlayerUsecase: playerUc,
DataLoader: dl,
}}))

// middleware
Expand All @@ -54,10 +59,15 @@ func InitializeGraphQLHandler(cfg config.Config) gin.HandlerFunc {
return
}

// DataLoaderのキャッシュをクリアする
dl.ClearAll()

// contextにuserIDを入れる
g5ctx.SetUserTokenGinContext(c, token)
g5ctx.SetOperationGinContext(c, g5ctx.OperationTypeUser)
c.Request = c.Request.WithContext(c)

// serve
h.ServeHTTP(c.Writer, c.Request)
}
}
Expand Down
1 change: 1 addition & 0 deletions backend/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ func main() {
cfg := config.GetConfig()

v1 := r.Group("/api/v1")
v1.Use(di.InitializeDatabaseConnectionMiddleware(cfg).Handle)
v1.POST("/login", di.InitializeUserLoginController(cfg).Handle)
v1.POST("/register", di.InitializeUserRegisterController(cfg).Handle)

Expand Down
40 changes: 20 additions & 20 deletions backend/controller/get5/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,32 +22,32 @@ func NewGot5MatchLoader(repositoryConnector database.RepositoryConnector) got5.M
}

type match struct {
m *entity.Match
match *entity.Get5Match
}

func (match *match) ToG5Format() got5.Match {
func (m *match) ToG5Format() got5.Match {
team1Players := map[string]string{}
for _, player := range match.m.Team1.Players {
for _, player := range m.match.Team1.Players {
team1Players[strconv.Itoa(int(player.SteamID))] = player.Name
}
team2Players := map[string]string{}
for _, player := range match.m.Team2.Players {
for _, player := range m.match.Team2.Players {
team2Players[strconv.Itoa(int(player.SteamID))] = player.Name
}

return got5.Match{
MatchTitle: match.m.Title,
MatchID: string(match.m.ID),
MatchTitle: m.match.Title,
MatchID: string(m.match.ID),
ClinchSeries: false,
NumMaps: int(match.m.MaxMaps),
NumMaps: int(m.match.MaxMaps),
Scrim: false,
Wingman: false,
PlayersPerTeam: 5,
CoachesPerTeam: 0,
CoachesMustReady: false,
MinPlayersToReady: 5,
MinSpectatorsToReady: 0,
SkipVeto: match.m.SkipVeto,
SkipVeto: m.match.SkipVeto,
VetoFirst: "random",
VetoMode: "",
SideType: "standard",
Expand All @@ -65,25 +65,25 @@ func (match *match) ToG5Format() got5.Match {
FavoredPercentageTeam1: 0,
FavoredPercentageText: "",
Team1: got5.Team{
ID: string(match.m.Team1.ID),
ID: string(m.match.Team1.ID),
Players: team1Players,
Coaches: map[string]string{},
Name: match.m.Team1.Name,
Tag: match.m.Team1.Tag,
Flag: match.m.Team1.Flag,
Logo: match.m.Team1.Logo,
Name: m.match.Team1.Name,
Tag: m.match.Team1.Tag,
Flag: m.match.Team1.Flag,
Logo: m.match.Team1.Logo,
SeriesScore: 0,
MatchText: "",
FromFile: "",
},
Team2: got5.Team{
ID: string(match.m.Team2.ID),
ID: string(m.match.Team2.ID),
Players: team2Players,
Coaches: map[string]string{},
Name: match.m.Team2.Name,
Tag: match.m.Team2.Tag,
Flag: match.m.Team2.Flag,
Logo: match.m.Team2.Logo,
Name: m.match.Team2.Name,
Tag: m.match.Team2.Tag,
Flag: m.match.Team2.Flag,
Logo: m.match.Team2.Logo,
SeriesScore: 0,
MatchText: "",
FromFile: "",
Expand All @@ -94,13 +94,13 @@ func (match *match) ToG5Format() got5.Match {

// Load implements got5.MatchLoader.
func (ml *matchLoader) Load(ctx context.Context, mid string) (got5.G5Match, error) {
uc := usecase.NewMatch(ml.repositoryConnector)
uc := usecase.NewGet5()
m, err := uc.GetMatch(ctx, entity.MatchID(mid))
if err != nil {
return nil, err
}
return &match{
m: m,
match: m,
}, nil

}
43 changes: 43 additions & 0 deletions backend/controller/gin/db.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package gin_controller

import (
"net/http"

"github.com/gin-gonic/gin"

"github.com/FlowingSPDG/get5loader/backend/gateway/database"
"github.com/FlowingSPDG/get5loader/backend/service/uuid"
)

type DatabaseConnectionMiddleware interface {
Handle(c *gin.Context)
}

type databaseConnectionMiddleware struct {
uuidGenerator uuid.UUIDGenerator
connector database.RepositoryConnector
}

func NewDatabaseConnectionMiddleware(
uuidGenerator uuid.UUIDGenerator,
connector database.RepositoryConnector,
) DatabaseConnectionMiddleware {
return &databaseConnectionMiddleware{
uuidGenerator: uuidGenerator,
connector: connector,
}
}

func (d *databaseConnectionMiddleware) Handle(c *gin.Context) {
if err := d.connector.Open(); err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"error": "internal server error",
})
return
}
defer d.connector.Close()

database.SetConnectionForGinContext(c, d.connector)

c.Next()
}
51 changes: 32 additions & 19 deletions backend/entity/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ type User struct {
Hash []byte
CreatedAt time.Time
UpdatedAt time.Time

Teams []*Team
Servers []*GameServer
Matches []*Match
}

type GameServer struct {
Expand All @@ -41,8 +37,8 @@ type GameServer struct {
type Match struct {
ID MatchID
UserID UserID
Team1 Team
Team2 Team
Team1ID TeamID
Team2ID TeamID
Winner TeamID // 0 for not decided yet
StartTime *time.Time
EndTime *time.Time
Expand All @@ -54,20 +50,29 @@ type Match struct {
Team2Score uint32
Forfeit *bool
Status MATCH_STATUS
Mapstats []*MapStat
}

type Get5Match struct {
ID MatchID
Team1 Get5Team
Team2 Get5Team
Winner TeamID // 0 for not decided yet
MaxMaps int32
Title string
SkipVeto bool
APIKey string
}

type MapStat struct {
ID MapStatsID
MatchID MatchID
MapNumber uint32
MapName string
StartTime *time.Time
EndTime *time.Time
Winner *TeamID
Team1Score uint32
Team2Score uint32
PlayerStats []*PlayerStat
ID MapStatsID
MatchID MatchID
MapNumber uint32
MapName string
StartTime *time.Time
EndTime *time.Time
Winner *TeamID
Team1Score uint32
Team2Score uint32
}

type PlayerStat struct {
Expand Down Expand Up @@ -108,13 +113,21 @@ type PlayerStat struct {
}

type Team struct {
ID TeamID
UserID UserID
Name string
Flag string
Tag string
Logo string
Public bool
}

type Get5Team struct {
ID TeamID
UserID UserID
Name string
Flag string
Tag string
Logo string
Public bool
Players []*Player
}

Expand Down
30 changes: 30 additions & 0 deletions backend/gateway/database/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package database

import (
"context"

"github.com/gin-gonic/gin"
)

var (
// RepositoryConnectorKey is a key to store repositoryConnector in gin.Context.
RepositoryConnectorKey = "repositoryConnector"
)

// GetConnectionFromGinContext gin.ContextからRepositoryConnectorを取得する
func GetConnectionFromGinContext(c *gin.Context) RepositoryConnector {
return c.MustGet(RepositoryConnectorKey).(RepositoryConnector)
}

// SetConnectionForGinContext gin.ContextにRepositoryConnectorを設定する
func SetConnectionForGinContext(c *gin.Context, repositoryConnector RepositoryConnector) {
c.Set(RepositoryConnectorKey, repositoryConnector)
}

func SetConnection(ctx context.Context, repositoryConnector RepositoryConnector) context.Context {
return context.WithValue(ctx, RepositoryConnectorKey, repositoryConnector)
}

func GetConnection(ctx context.Context) RepositoryConnector {
return ctx.Value(RepositoryConnectorKey).(RepositoryConnector)
}
Loading