feat: new API endpoint - GET /api/v2/versions/{versionCode}/servers/{serverKey}/tribes/{tribeId}
This commit is contained in:
parent
4ce2131ac4
commit
30be8bebc0
|
@ -149,7 +149,23 @@ paths:
|
||||||
$ref: "#/components/responses/ListTribesResponse"
|
$ref: "#/components/responses/ListTribesResponse"
|
||||||
default:
|
default:
|
||||||
$ref: "#/components/responses/ErrorResponse"
|
$ref: "#/components/responses/ErrorResponse"
|
||||||
|
/v2/versions/{versionCode}/servers/{serverKey}/tribes/{tribeId}:
|
||||||
|
get:
|
||||||
|
operationId: getTribe
|
||||||
|
tags:
|
||||||
|
- versions
|
||||||
|
- servers
|
||||||
|
- tribes
|
||||||
|
description: Get a tribe
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/components/parameters/VersionCodePathParam"
|
||||||
|
- $ref: "#/components/parameters/ServerKeyPathParam"
|
||||||
|
- $ref: "#/components/parameters/TribeIdPathParam"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
$ref: "#/components/responses/GetTribeResponse"
|
||||||
|
default:
|
||||||
|
$ref: "#/components/responses/ErrorResponse"
|
||||||
components:
|
components:
|
||||||
schemas:
|
schemas:
|
||||||
Error:
|
Error:
|
||||||
|
@ -993,6 +1009,13 @@ components:
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
|
TribeIdPathParam:
|
||||||
|
in: path
|
||||||
|
name: tribeId
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
minimum: 0
|
||||||
responses:
|
responses:
|
||||||
ListVersionsResponse:
|
ListVersionsResponse:
|
||||||
description: ""
|
description: ""
|
||||||
|
@ -1094,7 +1117,17 @@ components:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: "#/components/schemas/Tribe"
|
$ref: "#/components/schemas/Tribe"
|
||||||
|
GetTribeResponse:
|
||||||
|
description: ""
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- data
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
$ref: "#/components/schemas/Tribe"
|
||||||
ErrorResponse:
|
ErrorResponse:
|
||||||
description: Default error response.
|
description: Default error response.
|
||||||
content:
|
content:
|
||||||
|
|
|
@ -157,3 +157,32 @@ func (svc *TribeService) UpdateDominance(ctx context.Context, payload domain.Vil
|
||||||
func (svc *TribeService) List(ctx context.Context, params domain.ListTribesParams) (domain.ListTribesResult, error) {
|
func (svc *TribeService) List(ctx context.Context, params domain.ListTribesParams) (domain.ListTribesResult, error) {
|
||||||
return svc.repo.List(ctx, params)
|
return svc.repo.List(ctx, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (svc *TribeService) Get(
|
||||||
|
ctx context.Context,
|
||||||
|
id int,
|
||||||
|
serverKey string,
|
||||||
|
) (domain.Tribe, error) {
|
||||||
|
params := domain.NewListTribesParams()
|
||||||
|
if err := params.SetIDs([]int{id}); err != nil {
|
||||||
|
return domain.Tribe{}, err
|
||||||
|
}
|
||||||
|
if err := params.SetServerKeys([]string{serverKey}); err != nil {
|
||||||
|
return domain.Tribe{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := svc.repo.List(ctx, params)
|
||||||
|
if err != nil {
|
||||||
|
return domain.Tribe{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tribes := res.Tribes()
|
||||||
|
if len(tribes) == 0 {
|
||||||
|
return domain.Tribe{}, domain.TribeNotFoundError{
|
||||||
|
ID: id,
|
||||||
|
ServerKey: serverKey,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tribes[0], nil
|
||||||
|
}
|
||||||
|
|
|
@ -862,3 +862,29 @@ func (res ListTribesResult) Self() TribeCursor {
|
||||||
func (res ListTribesResult) Next() TribeCursor {
|
func (res ListTribesResult) Next() TribeCursor {
|
||||||
return res.next
|
return res.next
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TribeNotFoundError struct {
|
||||||
|
ID int
|
||||||
|
ServerKey string
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ ErrorWithParams = TribeNotFoundError{}
|
||||||
|
|
||||||
|
func (e TribeNotFoundError) Error() string {
|
||||||
|
return fmt.Sprintf("tribe with id %d and server key %s not found", e.ID, e.ServerKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e TribeNotFoundError) Type() ErrorType {
|
||||||
|
return ErrorTypeNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e TribeNotFoundError) Code() string {
|
||||||
|
return "tribe-not-found"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e TribeNotFoundError) Params() map[string]any {
|
||||||
|
return map[string]any{
|
||||||
|
"ID": e.ID,
|
||||||
|
"ServerKey": e.ServerKey,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -70,6 +70,7 @@ func NewAPIHTTPHandler(
|
||||||
middleware.NoCache,
|
middleware.NoCache,
|
||||||
h.versionMiddleware,
|
h.versionMiddleware,
|
||||||
h.serverMiddleware,
|
h.serverMiddleware,
|
||||||
|
h.tribeMiddleware,
|
||||||
},
|
},
|
||||||
ErrorHandlerFunc: func(w http.ResponseWriter, r *http.Request, err error) {
|
ErrorHandlerFunc: func(w http.ResponseWriter, r *http.Request, err error) {
|
||||||
apiErrorRenderer{errors: []error{err}}.render(w, r)
|
apiErrorRenderer{errors: []error{err}}.render(w, r)
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
package port
|
package port
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"gitea.dwysokinski.me/twhelp/corev3/internal/domain"
|
"gitea.dwysokinski.me/twhelp/corev3/internal/domain"
|
||||||
"gitea.dwysokinski.me/twhelp/corev3/internal/port/internal/apimodel"
|
"gitea.dwysokinski.me/twhelp/corev3/internal/port/internal/apimodel"
|
||||||
|
"github.com/go-chi/chi/v5"
|
||||||
)
|
)
|
||||||
|
|
||||||
//nolint:gocyclo
|
//nolint:gocyclo
|
||||||
|
@ -75,6 +79,60 @@ func (h *apiHTTPHandler) ListTribes(
|
||||||
renderJSON(w, r, http.StatusOK, apimodel.NewListTribesResponse(res))
|
renderJSON(w, r, http.StatusOK, apimodel.NewListTribesResponse(res))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *apiHTTPHandler) GetTribe(
|
||||||
|
w http.ResponseWriter,
|
||||||
|
r *http.Request,
|
||||||
|
_ apimodel.VersionCodePathParam,
|
||||||
|
_ apimodel.ServerKeyPathParam,
|
||||||
|
_ apimodel.TribeIdPathParam,
|
||||||
|
) {
|
||||||
|
tribe, _ := tribeFromContext(r.Context())
|
||||||
|
renderJSON(w, r, http.StatusOK, apimodel.NewGetTribeResponse(tribe))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *apiHTTPHandler) tribeMiddleware(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
routeCtx := chi.RouteContext(ctx)
|
||||||
|
server, serverOK := serverFromContext(ctx)
|
||||||
|
tribeIDIdx := slices.Index(routeCtx.URLParams.Keys, "tribeId")
|
||||||
|
|
||||||
|
if !serverOK || tribeIDIdx < 0 {
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tribeID, err := strconv.Atoi(routeCtx.URLParams.Values[tribeIDIdx])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tribe, err := h.tribeSvc.Get(
|
||||||
|
ctx,
|
||||||
|
tribeID,
|
||||||
|
server.Key(),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
apiErrorRenderer{errors: []error{err}, formatErrorPath: formatGetTribeErrorPath}.render(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
next.ServeHTTP(w, r.WithContext(tribeToContext(ctx, tribe)))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type tribeCtxKey struct{}
|
||||||
|
|
||||||
|
func tribeToContext(ctx context.Context, t domain.Tribe) context.Context {
|
||||||
|
return context.WithValue(ctx, tribeCtxKey{}, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func tribeFromContext(ctx context.Context) (domain.Tribe, bool) {
|
||||||
|
t, ok := ctx.Value(tribeCtxKey{}).(domain.Tribe)
|
||||||
|
return t, ok
|
||||||
|
}
|
||||||
|
|
||||||
func formatListTribesParamsErrorPath(segments []errorPathSegment) []string {
|
func formatListTribesParamsErrorPath(segments []errorPathSegment) []string {
|
||||||
if segments[0].model != "ListTribesParams" {
|
if segments[0].model != "ListTribesParams" {
|
||||||
return nil
|
return nil
|
||||||
|
@ -97,3 +155,20 @@ func formatListTribesParamsErrorPath(segments []errorPathSegment) []string {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func formatGetTribeErrorPath(segments []errorPathSegment) []string {
|
||||||
|
if segments[0].model != "ListTribesParams" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch segments[0].field {
|
||||||
|
case "ids":
|
||||||
|
path := []string{"$path", "ids"}
|
||||||
|
if segments[0].index >= 0 {
|
||||||
|
path = append(path, strconv.Itoa(segments[0].index))
|
||||||
|
}
|
||||||
|
return path
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -61,3 +61,9 @@ func NewListTribesResponse(res domain.ListTribesResult) ListTribesResponse {
|
||||||
|
|
||||||
return resp
|
return resp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewGetTribeResponse(t domain.Tribe) GetTribeResponse {
|
||||||
|
return GetTribeResponse{
|
||||||
|
Data: NewTribe(t),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user