From 5758c4784e37d98f2dead3a282a7a1674041ad58 Mon Sep 17 00:00:00 2001 From: tolelom <98kimsungmin@naver.com> Date: Mon, 16 Mar 2026 21:32:49 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20Internal=20API=EB=A5=BC=20Rate=20Limiter?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 데디케이트 서버 10개 인스턴스의 하트비트가 apiLimiter(IP당 60req/min)에 걸려 429 에러 발생. Internal API를 별도 그룹으로 분리하여 Rate Limit 제외. Co-Authored-By: Claude Opus 4.6 (1M context) --- routes/routes.go | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/routes/routes.go b/routes/routes.go index 302891e..8e5c89a 100644 --- a/routes/routes.go +++ b/routes/routes.go @@ -100,8 +100,16 @@ func Register( bossRaid.Post("/entry", brH.RequestEntryAuth) bossRaid.Get("/my-entry-token", brH.GetMyEntryToken) - // Internal - Boss Raid (API key auth) - br := api.Group("/internal/bossraid", middleware.ServerAuth) + // Player Profile (authenticated) + p := api.Group("/player", middleware.Auth) + p.Get("/profile", playerH.GetProfile) + p.Put("/profile", playerH.UpdateProfile) + + // ── Internal API (Rate Limit 제외, API Key 인증만) ────────────── + internalApi := app.Group("/api/internal", apiBodyLimit, middleware.ServerAuth) + + // Internal - Boss Raid + br := internalApi.Group("/bossraid") br.Post("/entry", brH.RequestEntry) br.Post("/start", brH.StartRaid) br.Post("/complete", middleware.IdempotencyRequired, brH.CompleteRaid) @@ -113,25 +121,20 @@ func Register( br.Post("/reset-room", brH.ResetRoom) br.Get("/server-status", brH.GetServerStatus) - // Player Profile (authenticated) - p := api.Group("/player", middleware.Auth) - p.Get("/profile", playerH.GetProfile) - p.Put("/profile", playerH.UpdateProfile) - - // Internal - Auth (API key auth) - internalAuth := api.Group("/internal/auth", middleware.ServerAuth) + // Internal - Auth + internalAuth := internalApi.Group("/auth") internalAuth.Post("/verify", authH.VerifyToken) - // Internal - Player (API key auth) - internalPlayer := api.Group("/internal/player", middleware.ServerAuth) + // Internal - Player + internalPlayer := internalApi.Group("/player") internalPlayer.Get("/profile", playerH.InternalGetProfile) internalPlayer.Post("/save", playerH.InternalSaveGameData) - // Internal - Game server endpoints (API key auth, username-based, idempotency-protected) - internal := api.Group("/internal/chain", middleware.ServerAuth) - internal.Post("/reward", middleware.IdempotencyRequired, chainH.InternalGrantReward) - internal.Post("/mint", middleware.IdempotencyRequired, chainH.InternalMintAsset) - internal.Get("/balance", chainH.InternalGetBalance) - internal.Get("/assets", chainH.InternalGetAssets) - internal.Get("/inventory", chainH.InternalGetInventory) + // Internal - Chain + internalChain := internalApi.Group("/chain") + internalChain.Post("/reward", middleware.IdempotencyRequired, chainH.InternalGrantReward) + internalChain.Post("/mint", middleware.IdempotencyRequired, chainH.InternalMintAsset) + internalChain.Get("/balance", chainH.InternalGetBalance) + internalChain.Get("/assets", chainH.InternalGetAssets) + internalChain.Get("/inventory", chainH.InternalGetInventory) }