spt-launcher/docs/endpoints.md

1098 lines
44 KiB
Markdown

# 공개 API 문서 (Public API Documentation)
이 문서는 코드 기준으로 확인 가능한 공개 엔드포인트(public endpoints)를 외부 공개용 문서 형식으로 정리한 것입니다.
라우팅 정의는 `Libraries/SPTarkov.Server.Core/Routers` 하위와 테스트 모드(TestMod)의 MVC 컨트롤러를 기준으로 합니다.
## 기본 정보 (Basics)
- 기본 URL(Base URL): `https://{HttpConfig.Ip}:{HttpConfig.Port}`
- 지원 메서드(Supported Methods): `GET`, `POST`, `PUT`
서버는 메서드(method)를 구분하지 않고 라우팅(route)만으로 처리합니다.
- 요청/응답 형식(Request/Response):
대부분 JSON(JSON)이며, 번들(bundle)/이미지(image)는 파일 응답(file response)입니다.
- 세션(Session):
`PHPSESSID` 쿠키(cookie)가 있을 경우 플레이어 컨텍스트(player context)로 처리됩니다.
## 라우팅 규칙 (Routing Rules)
- **정적 라우트(Static Route)**: URL이 정확히 일치(exact match)해야 처리됩니다.
- **동적 라우트(Dynamic Route)**: URL에 부분 일치(partial match)하면 처리됩니다.
예: `/client/locale/``/client/locale/en`에도 매칭됩니다.
---
## API 목록 (API Catalog)
### Achievements API
- `/client/achievement/list`
역할(Role): 업적 목록 조회(get achievements)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/achievement/statistic`
역할(Role): 업적 통계 조회(get achievement statistics)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
### Bots API
- `/client/game/bot/generate`
역할(Role): 봇 생성(generate bots)
사용법(Usage): 요청 바디 `GenerateBotsRequestData`
### Builds API
- `/client/builds/list`
역할(Role): 프리셋 목록 조회(get builds)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/builds/magazine/save`
역할(Role): 탄창 프리셋 저장(create magazine template)
사용법(Usage): 요청 바디 `SetMagazineRequest`
- `/client/builds/weapon/save`
역할(Role): 무기 프리셋 저장(set weapon build)
사용법(Usage): 요청 바디 `PresetBuildActionRequestData`
- `/client/builds/equipment/save`
역할(Role): 장비 프리셋 저장(set equipment build)
사용법(Usage): 요청 바디 `PresetBuildActionRequestData`
- `/client/builds/delete`
역할(Role): 프리셋 삭제(delete build)
사용법(Usage): 요청 바디 `RemoveBuildRequestData`
### Bundles API
- `/singleplayer/bundles`
역할(Role): 번들 목록 조회(get bundles list)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
### Client Logs API
- `/singleplayer/log`
역할(Role): 클라이언트 로그 수집(client log)
사용법(Usage): 요청 바디 `ClientLogRequest`
- `/singleplayer/release`
역할(Role): 릴리즈 노트 조회(release notes)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/singleplayer/enableBSGlogging`
역할(Role): BSG 로깅 플래그 처리(BSG logging flag)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
### Customization API
- `/client/trading/customization/storage`
역할(Role): 커스터마이징 보관함 조회(get customization unlocks)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/hideout/customization/offer/list`
역할(Role): 은신처 커스터마이징 목록 조회(get hideout customization offers)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/customization/storage`
역할(Role): 커스터마이징 저장소 조회(get customization storage)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
### Data API
- `/client/settings`
역할(Role): 설정 조회(get settings)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/globals`
역할(Role): 글로벌 데이터 조회(get globals)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/items`
역할(Role): 아이템 템플릿 조회(get template items)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/handbook/templates`
역할(Role): 핸드북 템플릿 조회(get handbook templates)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/customization`
역할(Role): 커스터마이징 템플릿 조회(get template suits)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/account/customization`
역할(Role): 캐릭터 커스터마이징 템플릿 조회(get template character)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/hideout/production/recipes`
역할(Role): 은신처 제작 레시피 조회(get hideout production recipes)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/hideout/settings`
역할(Role): 은신처 설정 조회(get hideout settings)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/hideout/areas`
역할(Role): 은신처 구역 조회(get hideout areas)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/languages`
역할(Role): 언어 목록 조회(get locale languages)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/hideout/qte/list`
역할(Role): QTE 목록 조회(get QTE list)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/dialogue`
역할(Role): 대화 데이터 조회(get dialogue)
사용법(Usage): 요청 바디 `GetClientDialogueRequestData`
### Dialogue/Friends API
- `/client/chatServer/list`
역할(Role): 채팅 서버 목록 조회(get chat server list)
사용법(Usage): 요청 바디 `GetChatServerListRequestData`
- `/client/mail/dialog/list`
역할(Role): 메일 대화 목록 조회(get mail dialog list)
사용법(Usage): 요청 바디 `GetMailDialogListRequestData`
- `/client/mail/dialog/view`
역할(Role): 메일 대화 조회(get mail dialog view)
사용법(Usage): 요청 바디 `GetMailDialogViewRequestData`
- `/client/mail/dialog/info`
역할(Role): 메일 대화 정보 조회(get mail dialog info)
사용법(Usage): 요청 바디 `GetMailDialogInfoRequestData`
- `/client/mail/dialog/remove`
역할(Role): 메일 대화 삭제(remove dialog)
사용법(Usage): 요청 바디 `RemoveDialogRequestData`
- `/client/mail/dialog/pin`
역할(Role): 메일 대화 고정(pin dialog)
사용법(Usage): 요청 바디 `PinDialogRequestData`
- `/client/mail/dialog/unpin`
역할(Role): 메일 대화 고정 해제(unpin dialog)
사용법(Usage): 요청 바디 `PinDialogRequestData`
- `/client/mail/dialog/read`
역할(Role): 메일 읽음 처리(set dialog read)
사용법(Usage): 요청 바디 `SetDialogReadRequestData`
- `/client/mail/dialog/getAllAttachments`
역할(Role): 모든 첨부 가져오기(get all attachments)
사용법(Usage): 요청 바디 `GetAllAttachmentsRequestData`
- `/client/mail/msg/send`
역할(Role): 메일 메시지 전송(send message)
사용법(Usage): 요청 바디 `SendMessageRequest`
- `/client/mail/dialog/clear`
역할(Role): 메일 정리(clear mail)
사용법(Usage): 요청 바디 `ClearMailMessageRequest`
- `/client/mail/dialog/group/create`
역할(Role): 그룹 메일 생성(create group mail)
사용법(Usage): 요청 바디 `CreateGroupMailRequest`
- `/client/mail/dialog/group/owner/change`
역할(Role): 그룹 메일 소유자 변경(change group mail owner)
사용법(Usage): 요청 바디 `ChangeGroupMailOwnerRequest`
- `/client/mail/dialog/group/users/add`
역할(Role): 그룹 메일 사용자 추가(add user to mail group)
사용법(Usage): 요청 바디 `AddUserGroupMailRequest`
- `/client/mail/dialog/group/users/remove`
역할(Role): 그룹 메일 사용자 제거(remove user from mail group)
사용법(Usage): 요청 바디 `RemoveUserGroupMailRequest`
- `/client/friend/list`
역할(Role): 친구 목록 조회(get friend list)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/friend/request/list/outbox`
역할(Role): 보낸 요청 목록(outbox) 조회(list outbox)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/friend/request/list/inbox`
역할(Role): 받은 요청 목록(inbox) 조회(list inbox)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/friend/request/send`
역할(Role): 친구 요청 전송(send friend request)
사용법(Usage): 요청 바디 `FriendRequestData`
- `/client/friend/request/accept-all`
역할(Role): 모든 친구 요청 수락(accept all requests)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/friend/request/accept`
역할(Role): 친구 요청 수락(accept request)
사용법(Usage): 요청 바디 `AcceptFriendRequestData`
- `/client/friend/request/decline`
역할(Role): 친구 요청 거절(decline request)
사용법(Usage): 요청 바디 `DeclineFriendRequestData`
- `/client/friend/request/cancel`
역할(Role): 친구 요청 취소(cancel request)
사용법(Usage): 요청 바디 `CancelFriendRequestData`
- `/client/friend/delete`
역할(Role): 친구 삭제(delete friend)
사용법(Usage): 요청 바디 `DeleteFriendRequest`
- `/client/friend/ignore/set`
역할(Role): 친구 차단 설정(ignore friend)
사용법(Usage): 요청 바디 `UIDRequestData`
- `/client/friend/ignore/remove`
역할(Role): 친구 차단 해제(unignore friend)
사용법(Usage): 요청 바디 `UIDRequestData`
### Game API
- `/client/game/config`
역할(Role): 게임 설정 조회(get game config)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/putHWMetrics`
역할(Role): 하드웨어 지표 전송(put HW metrics)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/game/mode`
역할(Role): 게임 모드 조회(get game mode)
사용법(Usage): 요청 바디 `GameModeRequestData`
- `/client/server/list`
역할(Role): 서버 목록 조회(get server list)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/match/group/current`
역할(Role): 현재 그룹 조회(get current group)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/game/version/validate`
역할(Role): 버전 검증(validate game version)
사용법(Usage): 요청 바디 `VersionValidateRequestData`
- `/client/game/start`
역할(Role): 게임 시작(start game)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/game/logout`
역할(Role): 로그아웃(logout)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/checkVersion`
역할(Role): 버전 확인(check version)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/game/keepalive`
역할(Role): 세션 유지(keepalive)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/singleplayer/settings/version`
역할(Role): 서버 버전 조회(get server version)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/reports/lobby/send`
역할(Role): 로비 신고 전송(send lobby report)
사용법(Usage): 요청 바디 `UIDRequestData`
- `/client/report/send`
역할(Role): 신고 전송(send report)
사용법(Usage): 요청 바디 `UIDRequestData`
- `/singleplayer/settings/getRaidTime`
역할(Role): 레이드 시간 설정 조회(get raid time)
사용법(Usage): 요청 바디 `GetRaidTimeRequest`
- `/client/survey`
역할(Role): 설문 조회(get survey)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/survey/view`
역할(Role): 설문 상세 조회(get survey view)
사용법(Usage): 요청 바디 `SendSurveyOpinionRequest`
- `/client/survey/opinion`
역할(Role): 설문 의견 전송(send survey opinion)
사용법(Usage): 요청 바디 `SendSurveyOpinionRequest`
- `/singleplayer/clientmods`
역할(Role): 클라이언트 모드 목록 수신(receive client mods)
사용법(Usage): 요청 바디 `SendClientModsRequest`
### Health API
- `/client/hideout/workout`
역할(Role): 은신처 운동 효과 처리(handle workout effects)
사용법(Usage): 요청 바디 `WorkoutData`
### Inraid API
- `/raid/profile/scavsave`
역할(Role): 스캐브 진행 저장(save scav progress)
사용법(Usage): 요청 바디 `ScavSaveRequestData`
- `/singleplayer/settings/raid/menu`
역할(Role): 레이드 메뉴 설정 조회(get raid menu settings)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/singleplayer/scav/traitorscavhostile`
역할(Role): 배신 스캐브 확률 조회(get traitor scav hostile chance)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/singleplayer/bosstypes`
역할(Role): 보스 타입 목록 조회(get boss types)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
### Insurance API
- `/client/insurance/items/list/cost`
역할(Role): 보험 비용 조회(get insurance cost)
사용법(Usage): 요청 바디 `GetInsuranceCostRequestData`
### Item Events API
- `/client/game/profile/items/moving`
역할(Role): 아이템 이벤트 처리(handle item events)
사용법(Usage): 요청 바디 `ItemEventRouterRequest`
분기 기준(Action): 아래 **Item Event Actions** 섹션 참고
### Launcher API
- `/launcher/ping`
역할(Role): 런처 핑(ping)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/launcher/server/connect`
역할(Role): 서버 연결(connect to server)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/launcher/profile/login`
역할(Role): 로그인(login)
사용법(Usage): 요청 바디 `LoginRequestData`
- `/launcher/profile/register`
역할(Role): 계정 등록(register)
사용법(Usage): 요청 바디 `RegisterData`
- `/launcher/profile/get`
역할(Role): 계정 조회(get profile)
사용법(Usage): 요청 바디 `LoginRequestData`
- `/launcher/profile/change/username`
역할(Role): 사용자명 변경(change username)
사용법(Usage): 요청 바디 `ChangeRequestData`
- `/launcher/profile/change/wipe`
역할(Role): 와이프(wipe)
사용법(Usage): 요청 바디 `RegisterData`
- `/launcher/profile/remove`
역할(Role): 계정 삭제(remove profile)
사용법(Usage): 요청 바디 `RemoveProfileData`
- `/launcher/profile/compatibleTarkovVersion`
역할(Role): 호환 버전 조회(get compatible version)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/launcher/server/version`
역할(Role): 서버 버전 조회(get server version)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/launcher/server/loadedServerMods`
역할(Role): 서버 로드 모드 목록(get loaded server mods)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/launcher/server/serverModsUsedByProfile`
역할(Role): 프로필 사용 모드 조회(get mods used by profile)
사용법(Usage): 요청 바디 `EmptyRequestData`
### Launcher V2 API
- `/launcher/v2/ping`
역할(Role): 런처 v2 핑(ping)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/launcher/v2/types`
역할(Role): 런처 v2 타입 조회(get types)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/launcher/v2/login`
역할(Role): 런처 v2 로그인(login)
사용법(Usage): 요청 바디 `LoginRequestData`
- `/launcher/v2/register`
역할(Role): 런처 v2 등록(register)
사용법(Usage): 요청 바디 `RegisterData`
- `/launcher/v2/remove`
역할(Role): 런처 v2 계정 삭제(remove)
사용법(Usage): 요청 바디 `LoginRequestData`
- `/launcher/v2/version`
역할(Role): 런처 v2 호환 버전 조회(compatible version)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/launcher/v2/mods`
역할(Role): 런처 v2 모드 목록 조회(mods)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/launcher/v2/profiles`
역할(Role): 런처 v2 프로필 목록 조회(profiles)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/launcher/v2/profile`
역할(Role): 런처 v2 프로필 조회(profile)
사용법(Usage): 요청 바디 `LoginRequestData`
- `/launcher/v2/wipe`
역할(Role): 런처 v2 와이프(wipe)
사용법(Usage): 요청 바디 `RegisterData`
### Locations API
- `/client/locations`
역할(Role): 위치 데이터 조회(get location data)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/airdrop/loot`
역할(Role): 에어드롭 전리품 조회(get airdrop loot)
사용법(Usage): 요청 바디 `GetAirdropLootRequest` (선택/optional)
### Match API
- `/client/match/available`
역할(Role): 매치 가능 여부 조회(check availability)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/match/updatePing`
역할(Role): 핑 업데이트(update ping)
사용법(Usage): 요청 바디 `UpdatePingRequestData`
- `/client/match/join`
역할(Role): 매치 참가(join match)
사용법(Usage): 요청 바디 `MatchGroupJoinRequest`
- `/client/match/exit`
역할(Role): 매치 종료(exit match)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/match/group/delete`
역할(Role): 그룹 삭제(delete group)
사용법(Usage): 요청 바디 `DeleteGroupRequest`
- `/client/match/group/leave`
역할(Role): 그룹 탈퇴(leave group)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/match/group/status`
역할(Role): 그룹 상태 조회(get group status)
사용법(Usage): 요청 바디 `MatchGroupStatusRequest`
- `/client/match/group/start_game`
역할(Role): 그룹장 게임 시작(start game as group leader)
사용법(Usage): 요청 바디 `MatchGroupStartGameRequest`
- `/client/match/group/exit_from_menu`
역할(Role): 메뉴에서 그룹 종료(exit from menu)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/match/group/current`
역할(Role): 현재 그룹 조회(get current group)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/match/group/looking/start`
역할(Role): 그룹 탐색 시작(start group search)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/match/group/looking/stop`
역할(Role): 그룹 탐색 종료(stop group search)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/match/group/invite/send`
역할(Role): 그룹 초대 전송(send invite)
사용법(Usage): 요청 바디 `MatchGroupInviteSendRequest`
- `/client/match/group/invite/accept`
역할(Role): 그룹 초대 수락(accept invite)
사용법(Usage): 요청 바디 `RequestIdRequest`
- `/client/match/group/invite/decline`
역할(Role): 그룹 초대 거절(decline invite)
사용법(Usage): 요청 바디 `RequestIdRequest`
- `/client/match/group/invite/cancel`
역할(Role): 그룹 초대 취소(cancel invite)
사용법(Usage): 요청 바디 `RequestIdRequest`
- `/client/match/group/invite/cancel-all`
역할(Role): 모든 그룹 초대 취소(cancel all invites)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/match/group/transfer`
역할(Role): 그룹장 위임(transfer group)
사용법(Usage): 요청 바디 `MatchGroupTransferRequest`
- `/client/match/group/raid/ready`
역할(Role): 레이드 준비 완료(raid ready)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/match/group/raid/not-ready`
역할(Role): 레이드 준비 해제(raid not ready)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/putMetrics`
역할(Role): 지표 전송(put metrics)
사용법(Usage): 요청 바디 `PutMetricsRequestData`
- `/client/analytics/event-disconnect`
역할(Role): 연결 해제 이벤트 전송(disconnect event)
사용법(Usage): 요청 바디 `PutMetricsRequestData`
- `/client/getMetricsConfig`
역할(Role): 지표 설정 조회(get metrics config)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/raid/configuration`
역할(Role): 레이드 구성 조회(get raid configuration)
사용법(Usage): 요청 바디 `GetRaidConfigurationRequestData`
- `/client/raid/configuration-by-profile`
역할(Role): 프로필 기반 레이드 구성 조회(get configuration by profile)
사용법(Usage): 요청 바디 `GetRaidConfigurationRequestData`
- `/client/match/group/player/remove`
역할(Role): 그룹 플레이어 제거(remove player from group)
사용법(Usage): 요청 바디 `MatchGroupPlayerRemoveRequest`
- `/client/match/local/start`
역할(Role): 로컬 레이드 시작(start local raid)
사용법(Usage): 요청 바디 `StartLocalRaidRequestData`
- `/client/match/local/end`
역할(Role): 로컬 레이드 종료(end local raid)
사용법(Usage): 요청 바디 `EndLocalRaidRequestData`
### Modded Trader Customization API
- `/singleplayer/moddedTraders`
역할(Role): 모드 트레이더 커스터마이징 조회(get modded trader customization)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
### Notifier API
- `/client/notifier/channel/create`
역할(Role): 노티파이어 채널 생성(create notifier channel)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/game/profile/select`
역할(Role): 프로필 선택(select profile)
사용법(Usage): 요청 바디 `UIDRequestData`
### Prestige API
- `/client/prestige/list`
역할(Role): 프레스티지 목록 조회(get prestige list)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/prestige/obtain`
역할(Role): 프레스티지 획득(obtain prestige)
사용법(Usage): 요청 바디 `ObtainPrestigeRequestList`
### Profile API
- `/client/game/profile/create`
역할(Role): 프로필 생성(create profile)
사용법(Usage): 요청 바디 `ProfileCreateRequestData`
- `/client/game/profile/list`
역할(Role): 프로필 목록 조회(get profile list)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/game/profile/savage/regenerate`
역할(Role): 스캐브 재생성(regenerate scav)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/game/profile/voice/change`
역할(Role): 보이스 변경(change voice)
사용법(Usage): 요청 바디 `ProfileChangeVoiceRequestData`
- `/client/game/profile/nickname/change`
역할(Role): 닉네임 변경(change nickname)
사용법(Usage): 요청 바디 `ProfileChangeNicknameRequestData`
- `/client/game/profile/nickname/validate`
역할(Role): 닉네임 유효성 검증(validate nickname)
사용법(Usage): 요청 바디 `ValidateNicknameRequestData`
- `/client/game/profile/nickname/reserved`
역할(Role): 예약 닉네임 조회(get reserved nickname)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/profile/status`
역할(Role): 프로필 상태 조회(get profile status)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/profile/view`
역할(Role): 다른 프로필 조회(get other profile)
사용법(Usage): 요청 바디 `GetOtherProfileRequest`
- `/client/profile/settings`
역할(Role): 프로필 설정 조회(get profile settings)
사용법(Usage): 요청 바디 `GetProfileSettingsRequest`
- `/client/game/profile/search`
역할(Role): 프로필 검색(search profiles)
사용법(Usage): 요청 바디 `SearchProfilesRequestData`
- `/launcher/profile/info`
역할(Role): 미니 프로필 조회(get mini profile)
사용법(Usage): 요청 바디 `GetMiniProfileRequestData`
- `/launcher/profiles`
역할(Role): 미니 프로필 목록 조회(get all mini profiles)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
### Quest API
- `/client/quest/list`
역할(Role): 퀘스트 목록 조회(list quests)
사용법(Usage): 요청 바디 `ListQuestsRequestData`
- `/client/repeatalbeQuests/activityPeriods`
역할(Role): 반복 퀘스트 기간 조회(get repeatable quest activity periods)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
### Ragfair API
- `/client/ragfair/search`
역할(Role): 플리마켓 검색(search ragfair)
사용법(Usage): 요청 바디 `SearchRequestData`
- `/client/ragfair/find`
역할(Role): 플리마켓 검색(search ragfair)
사용법(Usage): 요청 바디 `SearchRequestData`
- `/client/ragfair/itemMarketPrice`
역할(Role): 시세 조회(get market price)
사용법(Usage): 요청 바디 `GetMarketPriceRequestData`
- `/client/ragfair/offerfees`
역할(Role): 등록 수수료 계산(store offer fee)
사용법(Usage): 요청 바디 `StorePlayerOfferTaxAmountRequestData`
- `/client/reports/ragfair/send`
역할(Role): 플리마켓 신고 전송(send ragfair report)
사용법(Usage): 요청 바디 `SendRagfairReportRequestData`
- `/client/items/prices`
역할(Role): 플리마켓 가격 조회(get flea prices)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/ragfair/offer/findbyid`
역할(Role): 오퍼 조회(find offer by id)
사용법(Usage): 요청 바디 `GetRagfairOfferByIdRequest`
### Trader API
- `/client/trading/api/traderSettings`
역할(Role): 트레이더 설정 조회(get trader settings)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
### Weather API
- `/client/weather`
역할(Role): 날씨 조회(get weather)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/localGame/weather`
역할(Role): 로컬 게임 날씨 조회(get local weather)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
---
## 동적 라우트 API (Dynamic Routes)
동적 라우트(dynamic routes)는 아래 경로(prefix)로 매칭됩니다.
### Bots Dynamic API
- `/singleplayer/settings/bot/limit/`
역할(Role): 봇 제한 조회(get bot limit)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/singleplayer/settings/bot/difficulty/`
역할(Role): 봇 난이도 조회(get bot difficulty)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/singleplayer/settings/bot/difficulties`
역할(Role): 전체 난이도 목록 조회(get all bot difficulties)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/singleplayer/settings/bot/maxCap`
역할(Role): 봇 최대치 조회(get bot cap)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/singleplayer/settings/bot/getBotBehaviours/`
역할(Role): 봇 행동 조회(get bot behaviours)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
### Bundle Dynamic API
- `/files/bundle`
역할(Role): 번들 파일 제공(get bundle file)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
### Customization Dynamic API
- `/client/trading/customization/`
역할(Role): 트레이더 슈트 조회(get trader suits)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
### Data Dynamic API
- `/client/menu/locale/`
역할(Role): 메뉴 로케일 조회(get menu locale)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/locale/`
역할(Role): 로케일 조회(get locale)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/items/prices/`
역할(Role): 아이템 가격 조회(get item prices)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
### Inraid Dynamic API
- `/client/location/getLocalloot`
역할(Role): 로컬 루트 등록(register local loot)
사용법(Usage): 요청 바디 `RegisterPlayerRequestData`
### Notifier Dynamic API
- `/?last_id`
역할(Role): 노티파이어 폴링(notifier poll)
사용법(Usage): 요청 바디 없음(EmptyRequestData), 경로 패턴(path pattern)만 존재
- `/notifierServer`
역할(Role): 노티파이어 폴링(notifier poll)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/push/notifier/get/`
역할(Role): 노티파이어 정보 조회(get notifier)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
### Trader Dynamic API
- `/client/trading/api/getTrader/`
역할(Role): 트레이더 조회(get trader)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
- `/client/trading/api/getTraderAssort/`
역할(Role): 트레이더 재고 조회(get trader assort)
사용법(Usage): 요청 바디 없음(EmptyRequestData)
---
## Item Event Actions (아이템 이벤트 액션)
`/client/game/profile/items/moving``Action` 값에 따라 처리 로직이 분기됩니다.
### Inventory Actions
- `Move`, `Remove`, `Split`, `Merge`, `Transfer`, `Swap`, `Fold`, `Toggle`
- `Tag`, `Bind`, `Unbind`, `Examine`, `ReadEncyclopedia`
- `ApplyInventoryChanges`, `CreateMapMarker`, `DeleteMapMarker`, `EditMapMarker`
- `OpenRandomLootContainer`, `HideoutQuickTimeEvent`
- `RedeemProfileReward`, `SetFavoriteItems`, `QuestFail`, `PinLock`
- `SaveDialogueState`
### Quest Actions
- `QuestAccept`, `QuestComplete`, `QuestHandover`, `RepeatableQuestChange`
### Ragfair Actions
- `RagFairAddOffer`, `RagFairRemoveOffer`, `RagFairRenewOffer`
### Repair Actions
- `Repair`, `TraderRepair`
### Trade Actions
- `TradingConfirm`, `RagFairBuyOffer`, `SellAllFromSavage`
### Health Actions
- `Eat`, `Heal`, `RestoreHealth`
### Insurance Actions
- `Insure`
### Customization Actions
- `CustomizationBuy`, `CustomizationSet`
### Note Actions
- `AddNote`, `EditNote`, `DeleteNote`
### Wishlist Actions
- `AddToWishList`, `RemoveFromWishList`, `ChangeWishlistItemCategory`
### Hideout Actions (HideoutEventActions)
- `HideoutUpgrade`, `HideoutUpgradeComplete`
- `HideoutPutItemsInAreaSlots`, `HideoutTakeItemsFromAreaSlots`, `HideoutToggleArea`
- `HideoutSingleProductionStart`, `HideoutScavCaseProductionStart`, `HideoutContinuousProductionStart`
- `HideoutTakeProduction`, `RecordShootingRangePoints`, `HideoutImproveArea`
- `HideoutCancelProductionCommand`, `HideoutCircleOfCultistProductionStart`
- `HideoutDeleteProductionCommand`, `HideoutCustomizationApply`, `HideoutCustomizationSetMannequinPose`
---
## WebSocket (웹소켓)
- `/notifierServer/getwebsocket/{sessionId}`
역할(Role): 노티파이어 웹소켓 연결(websocket connection)
사용법(Usage): `{sessionId}`를 포함한 경로로 접속
---
## 파일/번들/이미지 (Files/Bundles/Images)
- 번들(bundle): `/files/bundle` (동적 라우트, 파일 응답)
- 이미지(image): `ImageRouter`는 런타임에 `AddRoute`로 등록된 경로만 처리합니다.
정적 목록은 코드 상에 고정되어 있지 않습니다.
---
## MVC 컨트롤러 예시 (Mod MVC Example)
- `GET /test/ping`
역할(Role): 테스트 핑(test ping)
사용법(Usage): 요청 바디 없음
응답 예시(Response Example):
```json
"Pong from MVC!"
```
# 공개 엔드포인트 (Public Endpoints)
이 문서는 서버에 노출된 공개 엔드포인트(public endpoints)를 전수조사하여 정리한 레퍼런스입니다.
라우팅 정의는 주로 `Libraries/SPTarkov.Server.Core/Routers` 아래에 있으며, 테스트용 MVC 컨트롤러(MVC controller)는 `Testing/TestMod/Controllers`에 있습니다.
## 기본 URL (Base URL)
- `https://{HttpConfig.Ip}:{HttpConfig.Port}`
설정 위치: `Libraries/SPTarkov.Server.Core/Models/Spt/Config/HttpConfig.cs`
## HTTP 메서드 (HTTP Methods)
- `SptHttpListener``GET`, `POST`, `PUT` 모두 수용하며, 라우팅 매칭은 메서드(method)를 구분하지 않습니다.
따라서 아래 목록은 **메서드 무관(method-agnostic)** 입니다.
## 라우팅 타입 (Routing Types)
- **StaticRouter (정적 라우터)**: URL을 **정확히 일치(exact match)** 시켜 처리합니다.
- **DynamicRouter (동적 라우터)**: URL이 **부분 일치(partial match)** 할 때 처리합니다.
예: `/client/locale/``/client/locale/en` 같은 하위 경로(prefix)에도 매칭됩니다.
---
## Static Routes (정적 라우트)
### `AchievementStaticRouter`
- `/client/achievement/list` (GetAchievements)
- `/client/achievement/statistic` (Statistic)
### `BotStaticRouter`
- `/client/game/bot/generate` (GenerateBots)
### `BuildStaticRouter`
- `/client/builds/list` (GetBuilds)
- `/client/builds/magazine/save` (CreateMagazineTemplate)
- `/client/builds/weapon/save` (SetWeapon)
- `/client/builds/equipment/save` (SetEquipment)
- `/client/builds/delete` (DeleteBuild)
### `BundleStaticRouter`
- `/singleplayer/bundles` (GetBundles)
### `ClientLogStaticRouter`
- `/singleplayer/log` (ClientLog)
- `/singleplayer/release` (ReleaseNotes)
- `/singleplayer/enableBSGlogging` (BsgLogging)
### `CustomizationStaticRouter`
- `/client/trading/customization/storage` (GetCustomisationUnlocks)
- `/client/hideout/customization/offer/list` (GetHideoutCustomisation)
- `/client/customization/storage` (GetStorage)
### `DataStaticRouter`
- `/client/settings` (GetSettings)
- `/client/globals` (GetGlobals)
- `/client/items` (GetTemplateItems)
- `/client/handbook/templates` (GetTemplateHandbook)
- `/client/customization` (GetTemplateSuits)
- `/client/account/customization` (GetTemplateCharacter)
- `/client/hideout/production/recipes` (GetHideoutProduction)
- `/client/hideout/settings` (GetHideoutSettings)
- `/client/hideout/areas` (GetHideoutAreas)
- `/client/languages` (GetLocalesLanguages)
- `/client/hideout/qte/list` (GetQteList)
- `/client/dialogue` (GetDialogue)
### `DialogStaticRouter`
- `/client/chatServer/list` (GetChatServerList)
- `/client/mail/dialog/list` (GetMailDialogList)
- `/client/mail/dialog/view` (GetMailDialogView)
- `/client/mail/dialog/info` (GetMailDialogInfo)
- `/client/mail/dialog/remove` (RemoveDialog)
- `/client/mail/dialog/pin` (PinDialog)
- `/client/mail/dialog/unpin` (UnpinDialog)
- `/client/mail/dialog/read` (SetRead)
- `/client/mail/dialog/getAllAttachments` (GetAllAttachments)
- `/client/mail/msg/send` (SendMessage)
- `/client/mail/dialog/clear` (ClearMail)
- `/client/mail/dialog/group/create` (CreateGroupMail)
- `/client/mail/dialog/group/owner/change` (ChangeMailGroupOwner)
- `/client/mail/dialog/group/users/add` (AddUserToMail)
- `/client/mail/dialog/group/users/remove` (RemoveUserFromMail)
- `/client/friend/list` (GetFriendList)
- `/client/friend/request/list/outbox` (ListOutbox)
- `/client/friend/request/list/inbox` (ListInbox)
- `/client/friend/request/send` (SendFriendRequest)
- `/client/friend/request/accept-all` (AcceptAllFriendRequests)
- `/client/friend/request/accept` (AcceptFriendRequest)
- `/client/friend/request/decline` (DeclineFriendRequest)
- `/client/friend/request/cancel` (CancelFriendRequest)
- `/client/friend/delete` (DeleteFriend)
- `/client/friend/ignore/set` (IgnoreFriend)
- `/client/friend/ignore/remove` (UnIgnoreFriend)
### `GameStaticRouter`
- `/client/game/config` (GetGameConfig)
- `/client/putHWMetrics` (PutHwMetrics)
- `/client/game/mode` (GetGameMode)
- `/client/server/list` (GetServer)
- `/client/match/group/current` (GetCurrentGroup)
- `/client/game/version/validate` (VersionValidate)
- `/client/game/start` (GameStart)
- `/client/game/logout` (GameLogout)
- `/client/checkVersion` (ValidateGameVersion)
- `/client/game/keepalive` (GameKeepalive)
- `/singleplayer/settings/version` (GetVersion)
- `/client/reports/lobby/send` (ReportNickname)
- `/client/report/send` (ReportNickname)
- `/singleplayer/settings/getRaidTime` (GetRaidTime)
- `/client/survey` (GetSurvey)
- `/client/survey/view` (GetSurveyView)
- `/client/survey/opinion` (SendSurveyOpinion)
- `/singleplayer/clientmods` (ReceiveClientMods)
### `HealthStaticRouter`
- `/client/hideout/workout` (HandleWorkoutEffects)
### `InraidStaticRouter`
- `/raid/profile/scavsave` (SaveProgress)
- `/singleplayer/settings/raid/menu` (GetRaidMenuSettings)
- `/singleplayer/scav/traitorscavhostile` (GetTraitorScavHostileChance)
- `/singleplayer/bosstypes` (GetBossTypes)
### `InsuranceStaticRouter`
- `/client/insurance/items/list/cost` (GetInsuranceCost)
### `ItemEventStaticRouter`
- `/client/game/profile/items/moving` (HandleEvents)
상세한 액션(action) 목록은 아래 **Item Event Actions** 섹션을 참고하세요.
### `LauncherStaticRouter`
- `/launcher/ping` (Ping)
- `/launcher/server/connect` (Connect)
- `/launcher/profile/login` (Login)
- `/launcher/profile/register` (Register)
- `/launcher/profile/get` (Get)
- `/launcher/profile/change/username` (ChangeUsername)
- `/launcher/profile/change/wipe` (Wipe)
- `/launcher/profile/remove` (RemoveProfile)
- `/launcher/profile/compatibleTarkovVersion` (GetCompatibleTarkovVersion)
- `/launcher/server/version` (GetServerVersion)
- `/launcher/server/loadedServerMods` (GetLoadedServerMods)
- `/launcher/server/serverModsUsedByProfile` (GetServerModsProfileUsed)
### `LauncherV2StaticRouter`
- `/launcher/v2/ping` (Ping)
- `/launcher/v2/types` (Types)
- `/launcher/v2/login` (Login)
- `/launcher/v2/register` (Register)
- `/launcher/v2/remove` (Remove)
- `/launcher/v2/version` (CompatibleVersion)
- `/launcher/v2/mods` (Mods)
- `/launcher/v2/profiles` (Profiles)
- `/launcher/v2/profile` (Profile)
- `/launcher/v2/wipe` (Wipe)
### `LocationStaticRouter`
- `/client/locations` (GetLocationData)
- `/client/airdrop/loot` (GetAirdropLoot)
### `MatchStaticRouter`
- `/client/match/available` (ServerAvailable)
- `/client/match/updatePing` (UpdatePing)
- `/client/match/join` (JoinMatch)
- `/client/match/exit` (ExitMatch)
- `/client/match/group/delete` (DeleteGroup)
- `/client/match/group/leave` (LeaveGroup)
- `/client/match/group/status` (GetGroupStatus)
- `/client/match/group/start_game` (StartGameAsGroupLeader)
- `/client/match/group/exit_from_menu` (ExitFromMenu)
- `/client/match/group/current` (GroupCurrent)
- `/client/match/group/looking/start` (StartGroupSearch)
- `/client/match/group/looking/stop` (StopGroupSearch)
- `/client/match/group/invite/send` (SendGroupInvite)
- `/client/match/group/invite/accept` (AcceptGroupInvite)
- `/client/match/group/invite/decline` (DeclineGroupInvite)
- `/client/match/group/invite/cancel` (CancelGroupInvite)
- `/client/match/group/invite/cancel-all` (CancelAllGroupInvite)
- `/client/match/group/transfer` (TransferGroup)
- `/client/match/group/raid/ready` (RaidReady)
- `/client/match/group/raid/not-ready` (NotRaidReady)
- `/client/putMetrics` (PutMetrics)
- `/client/analytics/event-disconnect` (EventDisconnect)
- `/client/getMetricsConfig` (GetMetrics)
- `/client/raid/configuration` (GetRaidConfiguration)
- `/client/raid/configuration-by-profile` (GetConfigurationByProfile)
- `/client/match/group/player/remove` (RemovePlayerFromGroup)
- `/client/match/local/start` (StartLocalRaid)
- `/client/match/local/end` (EndLocalRaid)
### `ModdedTraderCustomizationRouter`
- `/singleplayer/moddedTraders` (GetCustomizationTraders)
### `NotifierStaticRouter`
- `/client/notifier/channel/create` (CreateNotifierChannel)
- `/client/game/profile/select` (SelectProfile)
### `PrestigeStaticRouter`
- `/client/prestige/list` (GetPrestige)
- `/client/prestige/obtain` (ObtainPrestige)
### `ProfileStaticRouter`
- `/client/game/profile/create` (CreateProfile)
- `/client/game/profile/list` (GetProfileData)
- `/client/game/profile/savage/regenerate` (RegenerateScav)
- `/client/game/profile/voice/change` (ChangeVoice)
- `/client/game/profile/nickname/change` (ChangeNickname)
- `/client/game/profile/nickname/validate` (ValidateNickname)
- `/client/game/profile/nickname/reserved` (GetReservedNickname)
- `/client/profile/status` (GetProfileStatus)
- `/client/profile/view` (GetOtherProfile)
- `/client/profile/settings` (GetProfileSettings)
- `/client/game/profile/search` (SearchProfiles)
- `/launcher/profile/info` (GetMiniProfile)
- `/launcher/profiles` (GetAllMiniProfiles)
### `QuestStaticRouter`
- `/client/quest/list` (ListQuests)
- `/client/repeatalbeQuests/activityPeriods` (ActivityPeriods)
### `RagfairStaticRouter`
- `/client/ragfair/search` (Search)
- `/client/ragfair/find` (Search)
- `/client/ragfair/itemMarketPrice` (GetMarketPrice)
- `/client/ragfair/offerfees` (StorePlayerOfferTaxAmount)
- `/client/reports/ragfair/send` (SendReport)
- `/client/items/prices` (GetFleaPrices)
- `/client/ragfair/offer/findbyid` (GetFleaOfferById)
### `TraderStaticRouter`
- `/client/trading/api/traderSettings` (GetTraderSettings)
### `WeatherStaticRouter`
- `/client/weather` (GetWeather)
- `/client/localGame/weather` (GetLocalWeather)
---
## Dynamic Routes (동적 라우트)
동적 라우트(dynamic routes)는 **부분 일치(partial match)** 로 동작합니다.
아래 경로는 prefix로 사용됩니다.
### `BotDynamicRouter`
- `/singleplayer/settings/bot/limit/` (GetBotLimit)
- `/singleplayer/settings/bot/difficulty/` (GetBotDifficulty)
- `/singleplayer/settings/bot/difficulties` (GetAllBotDifficulties)
- `/singleplayer/settings/bot/maxCap` (GetBotCap)
- `/singleplayer/settings/bot/getBotBehaviours/` (GetBotBehaviours)
### `BundleDynamicRouter`
- `/files/bundle` (GetBundle)
### `CustomizationDynamicRouter`
- `/client/trading/customization/` (GetTraderSuits)
### `DataDynamicRouter`
- `/client/menu/locale/` (GetLocalesMenu)
- `/client/locale/` (GetLocalesGlobal)
- `/client/items/prices/` (GetItemPrices)
### `InraidDynamicRouter`
- `/client/location/getLocalloot` (RegisterPlayer)
### `NotifierDynamicRouter`
- `/?last_id` (Notify)
주의: `Path` 기준 부분 일치라서 `/` 경로에 대한 폴링(long-poll) 패턴으로 사용됩니다.
- `/notifierServer` (Notify)
- `/push/notifier/get/` (GetNotifier)
### `TraderDynamicRouter`
- `/client/trading/api/getTrader/` (GetTrader)
- `/client/trading/api/getTraderAssort/` (GetAssort)
### `LocationDynamicRouter`
- (라우트 없음)
`DynamicRouter`를 상속하지만 현재 등록된 경로가 없습니다.
---
## Item Event Actions (아이템 이벤트 액션)
`/client/game/profile/items/moving` 엔드포인트는 **Action 필드**에 따라 실제 처리가 분기됩니다.
아래는 처리 가능한 액션(action) 목록입니다.
### Inventory Actions
- `Move`, `Remove`, `Split`, `Merge`, `Transfer`, `Swap`, `Fold`, `Toggle`
- `Tag`, `Bind`, `Unbind`, `Examine`, `ReadEncyclopedia`
- `ApplyInventoryChanges`, `CreateMapMarker`, `DeleteMapMarker`, `EditMapMarker`
- `OpenRandomLootContainer`, `HideoutQuickTimeEvent`
- `RedeemProfileReward`, `SetFavoriteItems`, `QuestFail`, `PinLock`
- `SaveDialogueState`
### Quest Actions
- `QuestAccept`, `QuestComplete`, `QuestHandover`, `RepeatableQuestChange`
### Ragfair Actions
- `RagFairAddOffer`, `RagFairRemoveOffer`, `RagFairRenewOffer`
### Repair Actions
- `Repair`, `TraderRepair`
### Trade Actions
- `TradingConfirm`, `RagFairBuyOffer`, `SellAllFromSavage`
### Health Actions
- `Eat`, `Heal`, `RestoreHealth`
### Insurance Actions
- `Insure`
### Customization Actions
- `CustomizationBuy`, `CustomizationSet`
### Note Actions
- `AddNote`, `EditNote`, `DeleteNote`
### Wishlist Actions
- `AddToWishList`, `RemoveFromWishList`, `ChangeWishlistItemCategory`
### Hideout Actions (HideoutEventActions)
- `HideoutUpgrade`, `HideoutUpgradeComplete`
- `HideoutPutItemsInAreaSlots`, `HideoutTakeItemsFromAreaSlots`, `HideoutToggleArea`
- `HideoutSingleProductionStart`, `HideoutScavCaseProductionStart`, `HideoutContinuousProductionStart`
- `HideoutTakeProduction`, `RecordShootingRangePoints`, `HideoutImproveArea`
- `HideoutCancelProductionCommand`, `HideoutCircleOfCultistProductionStart`
- `HideoutDeleteProductionCommand`, `HideoutCustomizationApply`, `HideoutCustomizationSetMannequinPose`
---
## WebSocket (웹소켓)
- `/notifierServer/getwebsocket/{sessionId}`
핸들러(hook) 경로: `/notifierServer/getwebsocket/`
실제 연결은 경로에 세션 ID(sessionId)가 추가된 형태를 사용합니다.
---
## 파일/번들/이미지 제공 (Files/Bundles/Images)
- 번들(bundle): `/files/bundle...` (동적 라우트, `BundleDynamicRouter`)
- 이미지(image): `ImageRouter`는 런타임에 `AddRoute`로 등록된 경로만 처리합니다.
정적 목록은 코드 상에 고정되어 있지 않습니다.
---
## MVC 컨트롤러 (Mod Controller) 예시
테스트 모드(TestMod)에서 제공되는 예시 엔드포인트:
- `GET /test/ping` (TestController.Ping)
또한 `SPTWeb``app.MapControllers()`로 모드(mod)에서 제공하는 MVC 컨트롤러를 자동 등록합니다.