1. API 목록
투표는 PUT/DELETE 두 엔드포인트로 분리되어 있으며, 두 메서드 모두 멱등합니다.
-
PUT /teams/{teamId}/votes→ 투표 등록 (이미 등록된 경우 NO-OP, 200 OK) -
DELETE /teams/{teamId}/votes→ 투표 취소 (이미 취소된 경우 NO-OP, 200 OK)
| 두 메서드 모두 응답 본문에 사용자의 남은 투표 가능 횟수와 대회 최대 투표 허용 개수를 포함합니다. |
| 투표 등록 시 대회 최대 투표 수 초과 시 400 에러가 발생합니다. |
| 투표 기간 중에만 호출 가능하며, 투표 기간이 아닐 때 호출하면 400 에러가 발생합니다. |
2. PUT: 팀 투표 등록
해당 팀에 대해 투표를 등록합니다. 이미 투표한 상태에서 호출해도 동일하게 200 OK와 현재 카운트를 반환합니다 (멱등).
| Parameter | Description |
|---|---|
|
투표할 팀의 ID |
| Name | Description |
|---|---|
|
Bearer {accessToken} |
HTTP Request
PUT /teams/1/votes HTTP/1.1
Authorization: Bearer member.access.token
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
HTTP Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json;charset=UTF-8
Content-Length: 54
{
"remainingVotesCount" : 1,
"maxVotesLimit" : 2
}
| Path | Type | Description |
|---|---|---|
|
|
남은 투표 가능 횟수 |
|
|
대회 최대 투표 허용 개수 |
3. DELETE: 팀 투표 취소
해당 팀에 대한 투표를 취소합니다. 투표한 적 없는 팀에 호출해도 동일하게 200 OK와 현재 카운트를 반환합니다 (멱등).
| Parameter | Description |
|---|---|
|
투표를 취소할 팀의 ID |
| Name | Description |
|---|---|
|
Bearer {accessToken} |
HTTP Request
DELETE /teams/1/votes HTTP/1.1
Authorization: Bearer member.access.token
Host: localhost:8080
HTTP Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json;charset=UTF-8
Content-Length: 54
{
"remainingVotesCount" : 2,
"maxVotesLimit" : 2
}
| Path | Type | Description |
|---|---|---|
|
|
남은 투표 가능 횟수 |
|
|
대회 최대 투표 허용 개수 |
3.1. ⚠️ 실패 케이스
❌ Case 1: 존재하지 않는 팀
PUT /teams/999/votes HTTP/1.1
Authorization: Bearer member.access.token
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
HTTP/1.1 404 Not Found
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json;charset=UTF-8
Content-Length: 53
{
"message" : "팀이 존재하지 않습니다."
}
❌ Case 2: 최대 투표 수 초과
PUT /teams/3/votes HTTP/1.1
Authorization: Bearer member.access.token
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
HTTP/1.1 400 Bad Request
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json;charset=UTF-8
Content-Length: 76
{
"message" : "대회당 최대 2개 팀만 투표할 수 있습니다."
}
❌ Case 3: 투표 기간이 아닐 때 투표 등록
PUT /teams/1/votes HTTP/1.1
Authorization: Bearer member.access.token
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
HTTP/1.1 400 Bad Request
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json;charset=UTF-8
Content-Length: 60
{
"message" : "지금은 투표 기간이 아닙니다."
}
❌ Case 4: 투표 기간이 아닐 때 투표 취소
DELETE /teams/1/votes HTTP/1.1
Authorization: Bearer member.access.token
Host: localhost:8080
HTTP/1.1 400 Bad Request
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json;charset=UTF-8
Content-Length: 60
{
"message" : "지금은 투표 기간이 아닙니다."
}
4. GET: 사용자 남은 투표 개수 조회
| Parameter | Description |
|---|---|
|
대회 ID |
| Name | Description |
|---|---|
|
Bearer {accessToken} |
HTTP Request
GET /contests/1/votes/me HTTP/1.1
Authorization: Bearer member.access.token
Host: localhost:8080
HTTP Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json;charset=UTF-8
Content-Length: 54
{
"remainingVotesCount" : 1,
"maxVotesLimit" : 2
}
| Path | Type | Description |
|---|---|---|
|
|
남은 투표 가능 횟수 |
|
|
대회 최대 투표 허용 개수 |
4.1. ⚠️ 실패 케이스
❌ Case 1: 존재하지 않는 대회 ID
GET /contests/999/votes/me HTTP/1.1
Authorization: Bearer member.access.token
Host: localhost:8080
HTTP/1.1 404 Not Found
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json;charset=UTF-8
Content-Length: 56
{
"message" : "존재하지 않는 대회입니다."
}