mirror of
https://github.com/akyaiy/GoSally-mvp.git
synced 2026-01-05 14:12:25 +00:00
Project structure refactor:
- Change package name general_server to gateway - Changing the structure of directories and packages - Adding vendor to the project
This commit is contained in:
30
internal/server/gateway/general_types.go
Normal file
30
internal/server/gateway/general_types.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"net/http"
|
||||
|
||||
"github.com/akyaiy/GoSally-mvp/internal/engine/config"
|
||||
"github.com/akyaiy/GoSally-mvp/internal/server/rpc"
|
||||
)
|
||||
|
||||
// serversApiVer is a type alias for string, used to represent API version strings in the GeneralServer.
|
||||
type serversApiVer string
|
||||
|
||||
type ServerApiContract interface {
|
||||
GetVersion() string
|
||||
Handle(w http.ResponseWriter, r *http.Request, req rpc.RPCRequest)
|
||||
}
|
||||
|
||||
// GeneralServer implements the GeneralServerApiContract and serves as a router for different API versions.
|
||||
type GatewayServer struct {
|
||||
w http.ResponseWriter
|
||||
r *http.Request
|
||||
|
||||
// servers holds the registered servers by their API version.
|
||||
// The key is the version string, and the value is the server implementing GeneralServerApi
|
||||
servers map[serversApiVer]ServerApiContract
|
||||
|
||||
log *slog.Logger
|
||||
cfg *config.Conf
|
||||
}
|
||||
44
internal/server/gateway/init.go
Normal file
44
internal/server/gateway/init.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log/slog"
|
||||
|
||||
"github.com/akyaiy/GoSally-mvp/internal/engine/config"
|
||||
)
|
||||
|
||||
// GeneralServerInit structure only for initialization general server.
|
||||
type GatewayServerInit struct {
|
||||
Log *slog.Logger
|
||||
Config *config.Conf
|
||||
}
|
||||
|
||||
// InitGeneral initializes a new GeneralServer with the provided configuration and registered servers.
|
||||
func InitGateway(o *GatewayServerInit, servers ...ServerApiContract) *GatewayServer {
|
||||
general := &GatewayServer{
|
||||
servers: make(map[serversApiVer]ServerApiContract),
|
||||
cfg: o.Config,
|
||||
log: o.Log,
|
||||
}
|
||||
|
||||
// register the provided servers
|
||||
// s is each server implementing GeneralServerApiContract, this is not a general server
|
||||
for _, s := range servers {
|
||||
general.servers[serversApiVer(s.GetVersion())] = s
|
||||
}
|
||||
return general
|
||||
}
|
||||
|
||||
// GetVersion returns the API version of the GeneralServer, which is "general".
|
||||
func (s *GatewayServer) GetVersion() string {
|
||||
return "general"
|
||||
}
|
||||
|
||||
// AppendToArray adds a new server to the GeneralServer's internal map.
|
||||
func (s *GatewayServer) AppendToArray(server ServerApiContract) error {
|
||||
if _, exist := s.servers[serversApiVer(server.GetVersion())]; !exist {
|
||||
s.servers[serversApiVer(server.GetVersion())] = server
|
||||
return nil
|
||||
}
|
||||
return errors.New("server with this version is already exist")
|
||||
}
|
||||
80
internal/server/gateway/route.go
Normal file
80
internal/server/gateway/route.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
||||
"github.com/akyaiy/GoSally-mvp/internal/server/rpc"
|
||||
)
|
||||
|
||||
func (gs *GatewayServer) Handle(w http.ResponseWriter, r *http.Request) {
|
||||
var req rpc.RPCRequest
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
rpc.WriteRouterError(w, http.StatusBadRequest, &rpc.RPCError{
|
||||
JSONRPC: rpc.JSONRPCVersion,
|
||||
ID: nil,
|
||||
Error: map[string]any{
|
||||
"code": rpc.ErrInternalError,
|
||||
"message": rpc.ErrInternalErrorS,
|
||||
},
|
||||
})
|
||||
gs.log.Info("invalid request received", slog.String("issue", rpc.ErrInternalErrorS))
|
||||
return
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(body, &req); err != nil {
|
||||
rpc.WriteRouterError(w, http.StatusBadRequest, &rpc.RPCError{
|
||||
JSONRPC: rpc.JSONRPCVersion,
|
||||
ID: nil,
|
||||
Error: map[string]any{
|
||||
"code": rpc.ErrParseError,
|
||||
"message": rpc.ErrParseErrorS,
|
||||
},
|
||||
})
|
||||
gs.log.Info("invalid request received", slog.String("issue", rpc.ErrParseErrorS))
|
||||
return
|
||||
}
|
||||
|
||||
if req.JSONRPC != rpc.JSONRPCVersion {
|
||||
rpc.WriteRouterError(w, http.StatusBadRequest, &rpc.RPCError{
|
||||
JSONRPC: rpc.JSONRPCVersion,
|
||||
ID: req.ID,
|
||||
Error: map[string]any{
|
||||
"code": rpc.ErrInvalidRequest,
|
||||
"message": rpc.ErrInvalidRequestS,
|
||||
},
|
||||
})
|
||||
gs.log.Info("invalid request received", slog.String("issue", rpc.ErrInvalidRequestS), slog.String("requested-version", req.JSONRPC))
|
||||
return
|
||||
}
|
||||
|
||||
gs.Route(w, r, req)
|
||||
}
|
||||
|
||||
func (gs *GatewayServer) Route(w http.ResponseWriter, r *http.Request, req rpc.RPCRequest) {
|
||||
server, ok := gs.servers[serversApiVer(req.Params.ContextVersion)]
|
||||
if !ok {
|
||||
rpc.WriteRouterError(w, http.StatusBadRequest, &rpc.RPCError{
|
||||
JSONRPC: rpc.JSONRPCVersion,
|
||||
ID: req.ID,
|
||||
Error: map[string]any{
|
||||
"code": rpc.ErrContextVersion,
|
||||
"message": rpc.ErrContextVersionS,
|
||||
},
|
||||
})
|
||||
gs.log.Info("invalid request received", slog.String("issue", rpc.ErrContextVersionS), slog.String("requested-version", req.Params.ContextVersion))
|
||||
return
|
||||
}
|
||||
|
||||
// checks if request is notification
|
||||
if req.ID == nil {
|
||||
rr := httptest.NewRecorder()
|
||||
server.Handle(rr, r, req)
|
||||
return
|
||||
}
|
||||
server.Handle(w, r, req)
|
||||
}
|
||||
Reference in New Issue
Block a user