feat: api - add a new endpoint - GET /api/v2/versions/{versionCode}/servers/{serverKey}
This commit is contained in:
parent
79337cd60a
commit
6d61e43143
|
@ -67,6 +67,21 @@ paths:
|
|||
$ref: "#/components/responses/ListServersResponse"
|
||||
default:
|
||||
$ref: "#/components/responses/ErrorResponse"
|
||||
/v2/versions/{versionCode}/servers/{serverKey}:
|
||||
get:
|
||||
operationId: getServer
|
||||
tags:
|
||||
- versions
|
||||
- servers
|
||||
description: Get a server
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/VersionCodePathParam"
|
||||
- $ref: "#/components/parameters/ServerKeyPathParam"
|
||||
responses:
|
||||
200:
|
||||
$ref: "#/components/responses/GetServerResponse"
|
||||
default:
|
||||
$ref: "#/components/responses/ErrorResponse"
|
||||
components:
|
||||
schemas:
|
||||
Error:
|
||||
|
@ -205,6 +220,12 @@ components:
|
|||
required: true
|
||||
schema:
|
||||
type: string
|
||||
ServerKeyPathParam:
|
||||
in: path
|
||||
name: serverKey
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
ListVersionsResponse:
|
||||
description: ""
|
||||
|
@ -247,6 +268,17 @@ components:
|
|||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Server"
|
||||
GetServerResponse:
|
||||
description: ""
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- data
|
||||
properties:
|
||||
data:
|
||||
$ref: "#/components/schemas/Server"
|
||||
ErrorResponse:
|
||||
description: Default error response.
|
||||
content:
|
||||
|
|
|
@ -307,3 +307,36 @@ func (svc *ServerService) UpdatePlayerSnapshotsCreatedAt(
|
|||
|
||||
return svc.repo.Update(ctx, key, updateParams)
|
||||
}
|
||||
|
||||
func (svc *ServerService) GetNormalByVersionCodeAndServerKey(
|
||||
ctx context.Context,
|
||||
versionCode, key string,
|
||||
) (domain.Server, error) {
|
||||
params := domain.NewListServersParams()
|
||||
if err := params.SetVersionCodes([]string{versionCode}); err != nil {
|
||||
return domain.Server{}, err
|
||||
}
|
||||
if err := params.SetKeys([]string{key}); err != nil {
|
||||
return domain.Server{}, err
|
||||
}
|
||||
if err := params.SetSpecial(domain.NullBool{
|
||||
Value: false,
|
||||
Valid: true,
|
||||
}); err != nil {
|
||||
return domain.Server{}, err
|
||||
}
|
||||
|
||||
res, err := svc.repo.List(ctx, params)
|
||||
if err != nil {
|
||||
return domain.Server{}, err
|
||||
}
|
||||
|
||||
servers := res.Servers()
|
||||
if len(servers) == 0 {
|
||||
return domain.Server{}, domain.ServerNotFoundError{
|
||||
Key: key,
|
||||
}
|
||||
}
|
||||
|
||||
return servers[0], nil
|
||||
}
|
||||
|
|
|
@ -62,8 +62,12 @@ func NewAPIHTTPHandler(
|
|||
r.MethodNotAllowed(h.handleMethodNotAllowed)
|
||||
|
||||
return apimodel.HandlerWithOptions(h, apimodel.ChiServerOptions{
|
||||
BaseRouter: r,
|
||||
Middlewares: []apimodel.MiddlewareFunc{middleware.NoCache},
|
||||
BaseRouter: r,
|
||||
Middlewares: []apimodel.MiddlewareFunc{
|
||||
middleware.NoCache,
|
||||
h.versionMiddleware,
|
||||
h.serverMiddleware,
|
||||
},
|
||||
ErrorHandlerFunc: func(w http.ResponseWriter, r *http.Request, err error) {
|
||||
apiErrorRenderer{errors: []error{err}}.render(w, r)
|
||||
},
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
package port
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"slices"
|
||||
|
||||
"gitea.dwysokinski.me/twhelp/corev3/internal/domain"
|
||||
"gitea.dwysokinski.me/twhelp/corev3/internal/port/internal/apimodel"
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
func (h *apiHTTPHandler) ListServers(
|
||||
|
@ -58,6 +61,53 @@ func (h *apiHTTPHandler) ListServers(
|
|||
renderJSON(w, r, http.StatusOK, apimodel.NewListServersResponse(res))
|
||||
}
|
||||
|
||||
func (h *apiHTTPHandler) GetServer(
|
||||
w http.ResponseWriter,
|
||||
r *http.Request,
|
||||
_ apimodel.VersionCodePathParam,
|
||||
_ apimodel.ServerKeyPathParam,
|
||||
) {
|
||||
server, _ := serverFromContext(r.Context())
|
||||
renderJSON(w, r, http.StatusOK, apimodel.NewGetServerResponse(server))
|
||||
}
|
||||
|
||||
func (h *apiHTTPHandler) serverMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
routeCtx := chi.RouteContext(ctx)
|
||||
version, versionOK := versionFromContext(ctx)
|
||||
serverKeyIdx := slices.Index(routeCtx.URLParams.Keys, "serverKey")
|
||||
|
||||
if !versionOK || serverKeyIdx < 0 {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
server, err := h.serverSvc.GetNormalByVersionCodeAndServerKey(
|
||||
ctx,
|
||||
version.Code(),
|
||||
routeCtx.URLParams.Values[serverKeyIdx],
|
||||
)
|
||||
if err != nil {
|
||||
apiErrorRenderer{errors: []error{err}}.render(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r.WithContext(serverToContext(ctx, server)))
|
||||
})
|
||||
}
|
||||
|
||||
type serverCtxKey struct{}
|
||||
|
||||
func serverToContext(ctx context.Context, s domain.Server) context.Context {
|
||||
return context.WithValue(ctx, serverCtxKey{}, s)
|
||||
}
|
||||
|
||||
func serverFromContext(ctx context.Context) (domain.Server, bool) {
|
||||
s, ok := ctx.Value(serverCtxKey{}).(domain.Server)
|
||||
return s, ok
|
||||
}
|
||||
|
||||
func formatListServersParamsErrorPath(segments []errorPathSegment) []string {
|
||||
if segments[0].model != "ListServersParams" {
|
||||
return nil
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
package port
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"slices"
|
||||
|
||||
"gitea.dwysokinski.me/twhelp/corev3/internal/domain"
|
||||
"gitea.dwysokinski.me/twhelp/corev3/internal/port/internal/apimodel"
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
func (h *apiHTTPHandler) ListVersions(w http.ResponseWriter, r *http.Request, params apimodel.ListVersionsParams) {
|
||||
|
@ -33,16 +36,43 @@ func (h *apiHTTPHandler) ListVersions(w http.ResponseWriter, r *http.Request, pa
|
|||
renderJSON(w, r, http.StatusOK, apimodel.NewListVersionsResponse(res))
|
||||
}
|
||||
|
||||
func (h *apiHTTPHandler) GetVersion(w http.ResponseWriter, r *http.Request, versionCode apimodel.VersionCodePathParam) {
|
||||
version, err := h.versionSvc.Get(r.Context(), versionCode)
|
||||
if err != nil {
|
||||
apiErrorRenderer{errors: []error{err}}.render(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
func (h *apiHTTPHandler) GetVersion(w http.ResponseWriter, r *http.Request, _ apimodel.VersionCodePathParam) {
|
||||
version, _ := versionFromContext(r.Context())
|
||||
renderJSON(w, r, http.StatusOK, apimodel.NewGetVersionResponse(version))
|
||||
}
|
||||
|
||||
func (h *apiHTTPHandler) versionMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
routeCtx := chi.RouteContext(ctx)
|
||||
idx := slices.Index(routeCtx.URLParams.Keys, "versionCode")
|
||||
|
||||
if idx < 0 {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
version, err := h.versionSvc.Get(ctx, routeCtx.URLParams.Values[idx])
|
||||
if err != nil {
|
||||
apiErrorRenderer{errors: []error{err}}.render(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r.WithContext(versionToContext(ctx, version)))
|
||||
})
|
||||
}
|
||||
|
||||
type versionCtxKey struct{}
|
||||
|
||||
func versionToContext(ctx context.Context, v domain.Version) context.Context {
|
||||
return context.WithValue(ctx, versionCtxKey{}, v)
|
||||
}
|
||||
|
||||
func versionFromContext(ctx context.Context) (domain.Version, bool) {
|
||||
v, ok := ctx.Value(versionCtxKey{}).(domain.Version)
|
||||
return v, ok
|
||||
}
|
||||
|
||||
func formatListVersionsParamsErrorPath(segments []errorPathSegment) []string {
|
||||
if segments[0].model != "ListVersionsParams" {
|
||||
return nil
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
package apimodel
|
||||
|
||||
//go:generate oapi-codegen --config=config.yml ../../../../api/openapi3.yml
|
|
@ -54,3 +54,9 @@ func NewListServersResponse(res domain.ListServersResult) ListServersResponse {
|
|||
|
||||
return resp
|
||||
}
|
||||
|
||||
func NewGetServerResponse(v domain.Server) GetServerResponse {
|
||||
return GetServerResponse{
|
||||
Data: NewServer(v),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@ package apimodel
|
|||
|
||||
import "gitea.dwysokinski.me/twhelp/corev3/internal/domain"
|
||||
|
||||
//go:generate oapi-codegen --config=config.yml ../../../../api/openapi3.yml
|
||||
|
||||
func NewVersion(v domain.Version) Version {
|
||||
return Version{
|
||||
Code: v.Code(),
|
||||
|
|
Loading…
Reference in New Issue