사용자 API
사용자의 정보를 조회 및 수정할 수 있습니다.
Request Header 에는 Authorization: Bearer {access token}
와 같은 형식으로 보내야 하며, 사용자의 액세스 토큰
이 필요합니다.
사용자 조회
사용자의 정보를 조회합니다.
HTTP request
GET /api/member HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 122
{
"message" : "",
"data" : {
"nickname" : "HabitPay",
"imageUrl" : "https://picsum.photos/id/40/200/300"
}
}
Response fields
Path | Type | Description |
---|---|---|
|
|
메세지 |
|
|
사용자 닉네임 |
|
|
사용자 이미지 URL |
사용자 닉네임 변경
사용자의 닉네임을 변경합니다.
닉네임 규칙은 아래와 같습니다.
-
길이: 2~15자
-
문자: 영어 대소문자, 한글 (특수문자 제외)
HTTP request
PATCH /api/member/nickname HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer ACCESS_TOKEN
Content-Length: 33
Host: localhost:8080
{
"nickname" : "testNickname"
}
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 109
{
"message" : "닉네임 변경에 성공했습니다.",
"data" : {
"nickname" : "testNickname"
}
}
Response fields
Path | Type | Description |
---|---|---|
|
|
메세지 |
|
|
닉네임 |
에러 응답
1. 닉네임 규칙에 맞지 않는 경우 (400 Bad Request)
닉네임 규칙에 맞지 않는 경우입니다.
HTTP request
PATCH /api/member/nickname HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer ACCESS_TOKEN
Content-Length: 40
Host: localhost:8080
{
"nickname" : "invalid.#_!nickname"
}
HTTP response
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Content-Length: 142
{
"code" : "INVALID_NICKNAME_RULE",
"message" : "닉네임 규칙에 맞지 않습니다. (규칙: 길이 2~15자, 특수문자 제외)"
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
2. 이전과 동일한 닉네임인 경우 (400 Bad Request)
이전에 사용했던 닉네임과 동일한 닉네임을 사용한 경우입니다.
HTTP request
PATCH /api/member/nickname HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer ACCESS_TOKEN
Content-Length: 39
Host: localhost:8080
{
"nickname" : "duplicatedNickname"
}
HTTP response
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Content-Length: 117
{
"code" : "DUPLICATED_NICKNAME",
"message" : "이전과 동일한 닉네임으로 변경할 수 없습니다."
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
사용자 이미지 변경
사용자의 이미지를 변경합니다.
이미지 파일은 아래의 조건을 만족해야 합니다.
-
확장자: jpg, jpeg, png
-
크기: 1MB 이하
응답으로 반환되는 preSignedUrl
은 프론트엔드에서 S3 로 이미지를 직접 업로드 하기 위한 링크입니다.
HTTP request
PATCH /api/member/image HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer ACCESS_TOKEN
Content-Length: 54
Host: localhost:8080
{
"extension" : "jpg",
"contentLength" : 1048576
}
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 161
{
"message" : "프로필 이미지 변경에 성공했습니다.",
"data" : {
"preSignedUrl" : "https://{AWS S3 preSignedUrl to upload image file}"
}
}
Response fields
Path | Type | Description |
---|---|---|
|
|
메세지 |
|
|
AWS S3 업로드를 위한 preSignedUrl |
에러 응답
1. 이미지 크기가 초과한 경우 (400 Bad Request)
이미지 크기가 1MB 초과한 경우입니다.
HTTP request
PATCH /api/member/image HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer ACCESS_TOKEN
Content-Length: 57
Host: localhost:8080
{
"extension" : "jpg",
"contentLength" : 1073741824
}
HTTP response
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Content-Length: 135
{
"code" : "PROFILE_IMAGE_SIZE_TOO_LARGE",
"message" : "이미지 파일의 크기가 제한을 초과했습니다. (최대 1MB)"
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
2. 허용하지 않는 이미지 확장자인 경우 (400 Bad Request)
허용하는 이미지 확장자가 아닌 경우입니다.
HTTP request
PATCH /api/member/image HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer ACCESS_TOKEN
Content-Length: 67
Host: localhost:8080
{
"extension" : "invalidExtension",
"contentLength" : 1048576
}
HTTP response
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Content-Length: 139
{
"code" : "UNSUPPORTED_IMAGE_EXTENSION",
"message" : "지원하지 않는 이미지 확장자입니다. (png, jpg, jpeg 만 가능)"
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
회원 탈퇴
회원 탈퇴를 진행합니다.
반환되는 값은 DB 테이블의 Primary Key 에 해당하는 사용자의 ID 입니다.
HTTP request
DELETE /api/member HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 72
{
"message" : "정상적으로 탈퇴되었습니다.",
"data" : 1
}
Response fields
Path | Type | Description |
---|---|---|
|
|
메세지 |
|
|
Member ID |
챌린지 API
챌린지 정보 조회, 챌린지 생성, 챌린지 정보 수정을 수행하는 API 목록입니다.
전체 챌린지 목록 조회
전체 챌린지 목록을 조회합니다.
1페이지에 20개씩 반환합니다.
HTTP request
GET /api/challenges?page=page-number HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 596
{
"message" : "",
"data" : {
"content" : [ {
"id" : 1,
"title" : "챌린지 제목",
"startDate" : "2024-11-14T11:26:15.820761315Z",
"endDate" : "2024-11-19T11:26:15.820777846Z",
"stopDate" : null,
"numberOfParticipants" : 1,
"participatingDays" : 4,
"isStarted" : true,
"isEnded" : false,
"hostNickname" : "챌린지 주최자 닉네임",
"hostProfileImage" : "챌린지 주최자 프로필 이미지"
} ],
"page" : 1,
"size" : 1,
"totalElements" : 1,
"totalPages" : 1,
"hasNextPage" : false
}
}
Response fields
Path | Type | Description |
---|---|---|
|
|
메세지 |
|
|
챌린지 ID |
|
|
챌린지 제목 |
|
|
챌린지 시작 일시 |
|
|
챌린지 종료 일시 |
|
|
챌린지 중단 일시 |
|
|
챌린지 참여자 수 |
|
|
챌린지 총 진행 일 |
|
|
챌린지 시작 여부 |
|
|
챌린지 종료 여부 |
|
|
챌린지 주최자 닉네임 |
|
|
챌린지 주최자 프로필 이미지 |
|
|
현재 페이지 번호 |
|
|
현재 페이지 조회 결과 건수 |
|
|
전체 페이지 조회 결과 건수 |
|
|
전체 페이지 수 |
|
|
다음 페이지 존재 유무 |
나의 챌린지 참여 목록 조회
현재 접속한 사용자가 참여하고 있는 챌린지 목록을 반환합니다.
HTTP request
GET /api/challenges/me HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 606
{
"message" : "",
"data" : [ {
"challengeId" : 1,
"title" : "챌린지 제목",
"description" : "챌린지 설명",
"startDate" : "2024-11-14T11:26:16.21295216Z",
"endDate" : "2024-11-19T11:26:16.212967579Z",
"stopDate" : null,
"totalParticipatingDaysCount" : 2,
"numberOfParticipants" : 1,
"participatingDays" : 4,
"totalFee" : 1000,
"isPaidAll" : false,
"hostProfileImage" : "챌린지 주최자 프로필 이미지",
"isMemberGivenUp" : false,
"successCount" : 4,
"isTodayParticipatingDay" : true,
"isParticipatedToday" : false
} ]
}
Response fields
Path | Type | Description |
---|---|---|
|
|
메세지 |
|
|
챌린지 ID |
|
|
챌린지 제목 |
|
|
챌린지 설명 |
|
|
챌린지 시작 일시 |
|
|
챌린지 종료 일시 |
|
|
챌린지 중단 일시 |
|
|
챌린지 총 참여 일수 |
|
|
챌린지 참여 인원 |
|
|
챌린지 참여 요일 |
|
|
나의 벌금 합계 |
|
|
최종 정산 여부 |
|
|
챌린지 주최자 프로필 이미지 |
|
|
현재 사용자의 챌린지 포기 여부 |
|
|
챌린지 인증 성공 횟수 |
|
|
오늘 요일 == 챌린지 참여 요일 |
|
|
오늘 챌린지 참여 여부 |
챌린지 상세 정보 조회
첼린지의 상세 정보를 조회합니다.
참여 요일에 해당하는 participatingDays
는 비트 연산을 사용합니다.
7자리로 이루어진 2진수 0000000
를 기준으로 좌측부터 일월화수목금토
입니다.
예를 들어, 화요일
, 목요일
이 챌린지 참여 날짜라면, 2진수로 0010100
이고, 10진수로 변환하면 20
이 됩니다.
HTTP response 예시에 나온 participatingDays
의 값 4
는 10진수 4
를 의미하고 2진수로 0000011
이기 때문에 금요일
과 토요일
이 챌린지 참여 요일이 됩니다.
HTTP request
GET /api/challenges/1 HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 677
{
"message" : "",
"data" : {
"title" : "챌린지 제목",
"description" : "챌린지 설명",
"startDate" : "2024-11-14T11:26:16.097529208Z",
"endDate" : "2024-11-19T11:26:16.097545368Z",
"stopDate" : null,
"numberOfParticipants" : 1,
"participatingDays" : 4,
"feePerAbsence" : 1000,
"totalAbsenceFee" : 0,
"isPaidAll" : false,
"isTodayParticipatingDay" : true,
"isParticipatedToday" : true,
"hostNickname" : "챌린지 주최자 닉네임",
"enrolledMembersProfileImageList" : [ "imageLink1", "imageLink2", "imageLink3" ],
"isHost" : true,
"isMemberEnrolledInChallenge" : true,
"isGivenUp" : false
}
}
Response fields
Path | Type | Description |
---|---|---|
|
|
메세지 |
|
|
챌린지 제목 |
|
|
챌린지 설명 |
|
|
챌린지 시작 일시 |
|
|
챌린지 종료 일시 |
|
|
챌린지 중단 일시 |
|
|
챌린지 참여 인 |
|
|
챌린지 참여 요일 |
|
|
미참여 1회당 벌금 |
|
|
챌린지 전체 벌금 |
|
|
최종 정산 여부 |
|
|
챌린지 주최자 닉네임 |
|
|
챌린지 참여자 프로필 이미지 (최대 3명) |
|
|
현재 접속한 사용자 == 챌린지 주최자 |
|
|
현재 접속한 사용자의 챌린지 참여 여부 |
|
|
금일이 챌린지 참여일인지 여부 |
|
|
현재 접속한 사용자가 챌린지의 참가자일 경우, 금일 참여했는지 여부(참가자가 아니어도 false) |
|
|
챌린지 중도 포기 여부 |
에러 응답
챌린지가 존재하지 않는 경우 (404 Not Found)
존재하지 않는 챌린지를 조회한 경우입니다.
HTTP request
GET /api/challenges/0 HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
HTTP response
HTTP/1.1 404 Not Found
Content-Type: application/json;charset=UTF-8
Content-Length: 93
{
"code" : "CHALLENGE_NOT_FOUND",
"message" : "챌린지가 존재하지 않습니다."
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
챌린지 별 참여 기록 조회
챌린지 별 참여 기록을 조회합니다.
챌린지 별 달력의 참여 기록 표시를 위한 API입니다.
'참여 성공 날짜 목록', '참여 실패 날짜 목록', '앞으로 참여할 예정인 날짜 목록’의 세 가지 데이터가 제공됩니다.
ZoneId가 없는 날짜 데이터(시간 정보 없음)이기 때문에, 시간대 변환 없이 바로 사용할 수 있습니다.
'API 요청일’과 '참여일’이 동일한 경우, 이미 참여했다면 성공 목록에, 아직 참여하지 않았다면 예정 목록에 담기게 됩니다.
HTTP request
GET /api/challenges/1/records HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 148
{
"message" : "",
"data" : {
"successDayList" : [ "2024-11-14" ],
"failureDayList" : [ ],
"upcomingDayList" : [ "2024-11-21" ]
}
}
Response fields
Path | Type | Description |
---|---|---|
|
|
메세지 |
|
|
특정 챌린지 참여에 성공한 날짜 리스트 |
|
|
특정 챌린지 참여에 실패한 날짜 리스트 |
|
|
특정 챌린지 참여가 예정되어 있는 날짜 리스트 |
챌린지 생성
새로운 첼린지를 생성합니다.
HTTP request
POST /api/challenges HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer ACCESS_TOKEN
Content-Length: 223
Host: localhost:8080
{
"title" : "챌린지 제목",
"description" : "챌린지 설명",
"startDate" : "2024-11-14T12:26:16.185659508Z",
"endDate" : "2024-11-19T11:26:16.185690356Z",
"participatingDays" : 4,
"feePerAbsence" : 1000
}
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 376
{
"message" : "정상적으로 챌린지가 생성되었습니다.",
"data" : {
"hostNickname" : "IamHost",
"challengeId" : 1,
"title" : "챌린지 제목",
"description" : "챌린지 설명",
"startDate" : "2024-11-14T12:26:16.186165083Z",
"endDate" : "2024-11-19T11:26:16.186188156Z",
"participatingDays" : 4,
"feePerAbsence" : 1000
}
}
Response fields
Path | Type | Description |
---|---|---|
|
|
메세지 |
|
|
챌린지 주최자 닉네임 |
|
|
챌린지 ID |
|
|
챌린지 제목 |
|
|
챌린지 설명 |
|
|
챌린지 시작 일시 |
|
|
챌린지 종료 일시 |
|
|
챌린지 참여 요일 |
|
|
1회당 미참여 벌금 |
에러 응답
챌린지 시작 시간이 현재 시간보다 이전인 경우 (400 Bad Request)
챌린지 시작 시간이 현재 시간보다 이전인 경우입니다.
HTTP request
POST /api/challenges HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer ACCESS_TOKEN
Content-Length: 223
Host: localhost:8080
{
"title" : "챌린지 제목",
"description" : "챌린지 설명",
"startDate" : "2024-11-13T11:26:15.862002116Z",
"endDate" : "2024-11-19T11:26:15.862408375Z",
"participatingDays" : 4,
"feePerAbsence" : 1000
}
HTTP response
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Content-Length: 130
{
"code" : "CHALLENGE_START_TIME_INVALID",
"message" : "챌린지 시작 시간은 현재 시간 이후만 가능합니다."
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
챌린지 진행 기간에 참여 요일이 포함되지 않은 경우 (400 Bad Request)
챌린지 진행 기간에 선택한 참여 요일이 전혀 포함되지 않은 경우입니다.
예시
-
진행 기간: 2024.10.07(월) ~ 2024.10.08(화)
-
참여 요일: 수요일
HTTP request
POST /api/challenges HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer ACCESS_TOKEN
Content-Length: 214
Host: localhost:8080
{
"title" : "챌린지 제목",
"description" : "챌린지 설명",
"startDate" : "2024-10-07T00:00:00+09:00",
"endDate" : "2024-10-08T00:00:00+09:00",
"participatingDays" : 16,
"feePerAbsence" : 1000
}
HTTP response
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Content-Length: 164
{
"code" : "INVALID_CHALLENGE_PARTICIPATING_DAYS",
"message" : "챌린지 진행 기간에 선택한 챌린지 참여 요일이 포함되지 않았습니다."
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
챌린지 정보 수정
챌린지 정보를 수정합니다.
HTTP request
PATCH /api/challenges/1 HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer ACCESS_TOKEN
Content-Length: 40
Host: localhost:8080
{
"description" : "챌린지 설명"
}
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 335
{
"message" : "정상적으로 챌린지 정보 수정이 반영되었습니다.",
"data" : {
"title" : "챌린지 제목",
"description" : "챌린지 설명",
"startDate" : "2024-11-14T12:26:16.239484981Z",
"endDate" : "2024-11-19T11:26:16.239510679Z",
"participatingDays" : 4,
"feePerAbsence" : 1000
}
}
Response fields
Path | Type | Description |
---|---|---|
|
|
메세지 |
|
|
챌린지 제목 |
|
|
챌린지 설명 |
|
|
챌린지 시작 일시 |
|
|
챌린지 종료 일시 |
|
|
챌린지 참여 요일 |
|
|
1회당 미참여 벌금 |
에러 응답
챌린지 설명이 이전과 동일한 경우 (400 Bad Request)
챌린지 설명이 이전과 동일한 경우입니다.
HTTP request
PATCH /api/challenges/1 HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer ACCESS_TOKEN
Content-Length: 40
Host: localhost:8080
{
"description" : "챌린지 설명"
}
HTTP response
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Content-Length: 97
{
"code" : "DUPLICATED_CHALLENGE_DESCRIPTION",
"message" : "변경 사항이 없습니다."
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
챌린지 주최자가 아닌 경우 (403 Forbidden)
챌린지 주최자가 아닌 경우입니다.
HTTP request
PATCH /api/challenges/1 HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer ACCESS_TOKEN
Content-Length: 40
Host: localhost:8080
{
"description" : "챌린지 설명"
}
HTTP response
HTTP/1.1 403 Forbidden
Content-Type: application/json;charset=UTF-8
Content-Length: 101
{
"code" : "ONLY_HOST_CAN_MODIFY",
"message" : "챌린지 주최자만 수정 가능합니다."
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
챌린지 삭제
챌린지를 삭제합니다.
삭제는 챌린지 시작 시간 전까지만 가능하며, 챌린지 주최자만 삭제할 수 있습니다.
HTTP request
DELETE /api/challenges/1 HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 85
{
"message" : "정상적으로 챌린지를 삭제했습니다.",
"data" : null
}
Response fields
Path | Type | Description |
---|---|---|
|
|
메세지 |
|
|
null |
에러 응답
챌린지가 존재하지 않는 경우 (403 Forbidden)
챌린지 주최자가 아닌 경우 챌린지를 삭제하려는 경우입니다.
HTTP request
DELETE /api/challenges/1 HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
HTTP response
HTTP/1.1 403 Forbidden
Content-Type: application/json;charset=UTF-8
Content-Length: 125
{
"code" : "NOT_ALLOWED_TO_DELETE_CHALLENGE",
"message" : "챌린지 삭제는 챌린지 주최자만 가능합니다."
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
챌린지가 존재하지 않는 경우 (404 Not Found)
존재하지 않는 챌린지를 삭제하려는 경우입니다.
HTTP request
DELETE /api/challenges/0 HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
HTTP response
HTTP/1.1 404 Not Found
Content-Type: application/json;charset=UTF-8
Content-Length: 93
{
"code" : "CHALLENGE_NOT_FOUND",
"message" : "챌린지가 존재하지 않습니다."
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
챌린지 등록 관련 API
챌린지 등록 관련 API 목록입니다.
챌린지 참여자 등록
사용자를 챌린지 참여자에 등록합니다.
HTTP request
POST /api/challenges/1/enroll HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 183
{
"message" : "정상적으로 챌린지에 등록했습니다.",
"data" : {
"challengeId" : 1,
"memberId" : 1,
"enrolledDate" : "2024-11-14T11:26:17.367007895Z"
}
}
Response fields
Path | Type | Description |
---|---|---|
|
|
메세지 |
|
|
챌린지 ID |
|
|
사용자 ID |
|
|
챌린지 등록 일시 |
에러 응답
챌린지 등록 시간이 지난 경우 (400 Bad Request)
챌린지 시작 시간이 지나고 나서 등록하는 경우입니다.
HTTP request
POST /api/challenges/1/enroll HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
HTTP response
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Content-Length: 117
{
"code" : "INVALID_CHALLENGE_REGISTRATION_TIME",
"message" : "챌린지 등록 가능 시간이 아닙니다."
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
이미 참여한 챌린지인 경우 (409 Conflict)
이미 챌린지에 등록한 사용자가 다시 챌린지 등록하는 신청한 경우입니다.
HTTP request
POST /api/challenges/1/enroll HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
HTTP response
HTTP/1.1 409 Conflict
Content-Type: application/json;charset=UTF-8
Content-Length: 101
{
"code" : "ALREADY_ENROLLED_IN_CHALLENGE",
"message" : "이미 참여한 챌린지 입니다."
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
챌린지 등록 취소
등록한 챌린지를 취소합니다.
취소는 챌린지 시작 시간 이전까지만 가능합니다.
HTTP request
POST /api/challenges/1/cancel HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 92
{
"message" : "정상적으로 챌린지 등록을 취소했습니다.",
"data" : null
}
Response fields
Path | Type | Description |
---|---|---|
|
|
메세지 |
|
|
null |
에러 응답
챌린지 주최자가 등록 취소 하는 경우 (400 Bad Request)
챌린지 주최자는 등록을 취소할 수 없습니다.
HTTP request
POST /api/challenges/1/cancel HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
HTTP response
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Content-Length: 135
{
"code" : "NOT_ALLOWED_TO_CANCEL_ENROLLMENT_OF_HOST",
"message" : "챌린지 주최자는 참여 취소가 불가능 합니다."
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
챌린지에 참여하지 않은 경우 (400 Bad Request)
참여하지 않은 챌린지를 취소하는 경우입니다.
HTTP request
POST /api/challenges/1/cancel HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
HTTP response
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Content-Length: 100
{
"code" : "NOT_ENROLLED_IN_CHALLENGE",
"message" : "참여하지 않은 챌린지 입니다."
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
챌린지 등록 취소 시간을 지난 경우 (400 Bad Request)
챌린지가 시작하고 나서 등록 취소를 하는 경우입니다.
HTTP request
POST /api/challenges/1/cancel HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
HTTP response
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Content-Length: 123
{
"code" : "INVALID_CHALLENGE_CANCELLATION_TIME",
"message" : "챌린지 취소 가능한 시간이 지났습니다."
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
챌린지 중도 포기
시작한 챌린지를 중도 포기합니다.
중도 포기 이후에는 해당 챌린지에 게시물 생성, 수정, 삭제가 불가능 합니다.
HTTP request
POST /api/challenges/1/give-up HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 103
{
"message" : "정상적으로 챌린지 중도 포기 처리가 되었습니다.",
"data" : null
}
Response fields
Path | Type | Description |
---|---|---|
|
|
메세지 |
|
|
null |
에러 응답
챌린지 시작 시간 이전 (400 Bad Request)
이미 중도 포기한 경우 다시 중도 포기 요청을 보낼 수 없습니다.
HTTP request
POST /api/challenges/1/give-up HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
HTTP response
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Content-Length: 136
{
"code" : "TOO_EARLY_GIVEN_UP_CHALLENGE",
"message" : "챌린지 중도 포기는 챌린지 시작 이후에만 가능합니다."
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
이미 중도 포기한 경우 (400 Bad Request)
이미 중도 포기한 경우 다시 중도 포기 요청을 보낼 수 없습니다.
HTTP request
POST /api/challenges/1/give-up HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
HTTP response
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Content-Length: 105
{
"code" : "ALREADY_GIVEN_UP_CHALLENGE",
"message" : "이미 중도 포기한 챌린지 입니다."
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
챌린지 포스트 API
챌린지 포스트를 등록, 조회, 수정 및 삭제할 수 있습니다.
Request Header 에는 Authorization: Bearer {access token}
와 같은 형식으로 보내야 하며, 사용자의 액세스 토큰
이 필요합니다.
챌린지 포스트 조회
경로 변수로 받은 post의 id값을 이용해 특정 챌린지 포스트를 조회합니다.
HTTP request
GET /api/posts/1 HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 560
{
"message" : "",
"data" : {
"id" : 1,
"challengeId" : 1,
"content" : "This is test post.",
"writer" : "test user",
"isPostAuthor" : true,
"profileUrl" : "https://picsum.photos/id/40/200/300",
"isAnnouncement" : false,
"createdAt" : "2024-11-14T11:26:14.460072005",
"photoViewList" : [ {
"postPhotoId" : 1,
"viewOrder" : 1,
"imageUrl" : "https://picsum.photos/id/40/200/300"
}, {
"postPhotoId" : 2,
"viewOrder" : 2,
"imageUrl" : "https://picsum.photos/id/40/200/300"
} ]
}
}
Response fields
Path | Type | Description |
---|---|---|
|
|
응답 메시지 |
|
|
응답 데이터 |
|
|
포스트 id |
|
|
포스트가 소속된 challenge id |
|
|
포스트 내용 |
|
|
작성자 |
|
|
요청한 멤버가 작성자 본인인지 여부 |
|
|
작성자 프로필 이미지 URL |
|
|
공지글 여부 |
|
|
생성 일시 |
|
|
포스트 포토(URL 포함) 데이터를 담은 객체 배열 |
|
|
포토 id |
|
|
포스트 내 포토의 순서 |
|
|
포스트 포토 url |
챌린지 내 전체 포스트 조회
경로 변수로 받은 challenge의 id값을 이용해 해당 챌린지 내의 모든 포스트를 조회합니다. 해당 챌린지에 등록되어 있는 멤버만 포스트를 조회할 수 있습니다.
(포스트 목록을 반환하는 뒤이은 모든 메서드가 그렇습니다만,) 복수의 포스트를 반환하는 API는 페이지네이션 메타 데이터와 함께 반환됩니다.
data의 content에는 포스트 뷰 객체가 배열로 담깁니다.
data의 pageable 객체에는 페이지네이션 정보가 담겨있습니다. 그러나 pageable 객체에 접근하지 않아도 바로 사용할 수 있는 메타 데이터가 추가로 존재합니다.
data에서 content 배열, pageable 객체를 지나면 바로 페이징 메타 데이터가 존재합니다. 특히 현재 페이지가 마지막 페이지인지 boolean으로 알려주는 "last" 속성이 있으므로, 이를 활용할 수 있습니다.
HTTP request
GET /api/challenges/1/posts HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 1370
{
"message" : "",
"data" : {
"content" : [ {
"id" : 1,
"challengeId" : 1,
"content" : "This is test post 1.",
"writer" : "test user",
"isPostAuthor" : true,
"profileUrl" : "",
"isAnnouncement" : false,
"createdAt" : "2024-11-14T11:26:14.82970346",
"photoViewList" : [ {
"postPhotoId" : 1,
"viewOrder" : 1,
"imageUrl" : "https://picsum.photos/id/40/200/300"
} ]
}, {
"id" : 2,
"challengeId" : 2,
"content" : "This is test post 2.",
"writer" : "test user2",
"isPostAuthor" : false,
"profileUrl" : "https://picsum.photos/id/40/200/300",
"isAnnouncement" : false,
"createdAt" : "2024-11-14T11:26:14.829726924",
"photoViewList" : [ {
"postPhotoId" : 2,
"viewOrder" : 2,
"imageUrl" : "https://picsum.photos/id/40/200/300"
} ]
} ],
"pageable" : {
"pageNumber" : 0,
"pageSize" : 10,
"sort" : {
"empty" : true,
"sorted" : false,
"unsorted" : true
},
"offset" : 0,
"paged" : true,
"unpaged" : false
},
"size" : 10,
"number" : 0,
"sort" : {
"empty" : true,
"sorted" : false,
"unsorted" : true
},
"numberOfElements" : 2,
"first" : true,
"last" : false,
"empty" : false
}
}
Response fields
Path | Type | Description |
---|---|---|
|
|
응답 메시지 |
|
|
응답 데이터 |
|
|
포스트 뷰 목록 |
|
|
포스트 id |
|
|
포스트가 소속된 challenge id |
|
|
포스트 내용 |
|
|
작성자 |
|
|
요청한 멤버가 작성자 본인인지 여부 |
|
|
작성자 프로필 이미지 URL |
|
|
공지글 여부 |
|
|
생성 일시 |
|
|
포스트 포토(URL 포함) 데이터를 담은 객체 배열 |
|
|
포토 id |
|
|
포스트 내 포토의 순서 |
|
|
포스트 포토 url |
|
|
포스트 뷰 페이지네이션 정보를 담은 Pageable 객체 |
|
|
현재 페이지 번호 |
|
|
한 페이지에 포함되는 항목의 수 |
|
|
정렬 정보 |
|
|
정렬 조건이 없는지 여부 |
|
|
정렬되지 않았는지 여부 |
|
|
정렬되었는지 여부 |
|
|
페이징된 항목의 시작 위치 |
|
|
페이징된 요청인지 여부 |
|
|
페이징되지 않은 요청인지 여부 |
|
|
한 페이지에 포함되는 항목의 수 |
|
|
현재 페이지 번호 |
|
|
정렬 정보 |
|
|
정렬 조건이 없는지 여부 |
|
|
정렬되지 않았는지 여부 |
|
|
정렬되었는지 여부 |
|
|
현재 페이지에 있는 요소의 수 |
|
|
이 페이지가 첫 번째 페이지인지 여부 |
|
|
이 페이지가 마지막 페이지인지 여부 |
|
|
페이지가 비어있는지 여부 |
챌린지 내 전체 포스트 중 공지 포스트 조회
경로 변수로 받은 challenge의 id값을 이용해 해당 챌린지 내의 모든 공지 포스트를 조회합니다. 해당 챌린지에 등록되어 있는 멤버만 조회할 수 있습니다.
HTTP request
GET /api/challenges/1/posts/announcements HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 1395
{
"message" : "",
"data" : {
"content" : [ {
"id" : 1,
"challengeId" : 1,
"content" : "This is announcement test post 1.",
"writer" : "test user",
"isPostAuthor" : false,
"profileUrl" : "",
"isAnnouncement" : true,
"createdAt" : "2024-11-14T11:26:14.600259377",
"photoViewList" : [ {
"postPhotoId" : 1,
"viewOrder" : 1,
"imageUrl" : "https://picsum.photos/id/40/200/300"
} ]
}, {
"id" : 2,
"challengeId" : 2,
"content" : "This is announcement test post 2.",
"writer" : "test user",
"isPostAuthor" : false,
"profileUrl" : "https://picsum.photos/id/40/200/300",
"isAnnouncement" : true,
"createdAt" : "2024-11-14T11:26:14.600302006",
"photoViewList" : [ {
"postPhotoId" : 2,
"viewOrder" : 2,
"imageUrl" : "https://picsum.photos/id/40/200/300"
} ]
} ],
"pageable" : {
"pageNumber" : 0,
"pageSize" : 10,
"sort" : {
"empty" : true,
"sorted" : false,
"unsorted" : true
},
"offset" : 0,
"paged" : true,
"unpaged" : false
},
"size" : 10,
"number" : 0,
"sort" : {
"empty" : true,
"sorted" : false,
"unsorted" : true
},
"numberOfElements" : 2,
"first" : true,
"last" : false,
"empty" : false
}
}
Response fields
Path | Type | Description |
---|---|---|
|
|
응답 메시지 |
|
|
응답 데이터 |
|
|
포스트 뷰 목록 |
|
|
포스트 id |
|
|
포스트가 소속된 challenge id |
|
|
포스트 내용 |
|
|
작성자 |
|
|
요청한 멤버가 작성자 본인인지 여부 |
|
|
작성자 프로필 이미지 URL |
|
|
공지글 여부 |
|
|
생성 일시 |
|
|
포스트 포토(URL 포함) 데이터를 담은 객체 배열 |
|
|
포토 id |
|
|
포스트 내 포토의 순서 |
|
|
포스트 포토 url |
|
|
포스트 뷰 페이지네이션 정보를 담은 Pageable 객체 |
|
|
현재 페이지 번호 |
|
|
한 페이지에 포함되는 항목의 수 |
|
|
정렬 정보 |
|
|
정렬 조건이 없는지 여부 |
|
|
정렬되지 않았는지 여부 |
|
|
정렬되었는지 여부 |
|
|
페이징된 항목의 시작 위치 |
|
|
페이징된 요청인지 여부 |
|
|
페이징되지 않은 요청인지 여부 |
|
|
한 페이지에 포함되는 항목의 수 |
|
|
현재 페이지 번호 |
|
|
정렬 정보 |
|
|
정렬 조건이 없는지 여부 |
|
|
정렬되지 않았는지 여부 |
|
|
정렬되었는지 여부 |
|
|
현재 페이지에 있는 요소의 수 |
|
|
이 페이지가 첫 번째 페이지인지 여부 |
|
|
이 페이지가 마지막 페이지인지 여부 |
|
|
페이지가 비어있는지 여부 |
챌린지 내 본인이 작성한 모든 포스트 조회
경로 변수로 받은 challenge의 id값을 이용해 해당 챌린지 내에서 본인이 작성한 모든 포스트를 조회합니다. '본인’이란 요청을 보낸 멤버를 의미합니다.
HTTP request
GET /api/challenges/1/posts/me HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 1381
{
"message" : "",
"data" : {
"content" : [ {
"id" : 1,
"challengeId" : 1,
"content" : "This is test post 1 by me.",
"writer" : "test user",
"isPostAuthor" : true,
"profileUrl" : "",
"isAnnouncement" : false,
"createdAt" : "2024-11-14T11:26:14.745184309",
"photoViewList" : [ {
"postPhotoId" : 1,
"viewOrder" : 1,
"imageUrl" : "https://picsum.photos/id/40/200/300"
} ]
}, {
"id" : 2,
"challengeId" : 2,
"content" : "This is test post 2 by me.",
"writer" : "test user",
"isPostAuthor" : true,
"profileUrl" : "https://picsum.photos/id/40/200/300",
"isAnnouncement" : false,
"createdAt" : "2024-11-14T11:26:14.745208635",
"photoViewList" : [ {
"postPhotoId" : 2,
"viewOrder" : 2,
"imageUrl" : "https://picsum.photos/id/40/200/300"
} ]
} ],
"pageable" : {
"pageNumber" : 0,
"pageSize" : 10,
"sort" : {
"empty" : true,
"sorted" : false,
"unsorted" : true
},
"offset" : 0,
"paged" : true,
"unpaged" : false
},
"size" : 10,
"number" : 0,
"sort" : {
"empty" : true,
"sorted" : false,
"unsorted" : true
},
"numberOfElements" : 2,
"first" : true,
"last" : false,
"empty" : false
}
}
Response fields
Path | Type | Description |
---|---|---|
|
|
응답 메시지 |
|
|
응답 데이터 |
|
|
포스트 뷰 목록 |
|
|
포스트 id |
|
|
포스트가 소속된 challenge id |
|
|
포스트 내용 |
|
|
작성자 |
|
|
요청한 멤버가 작성자 본인인지 여부 |
|
|
작성자 프로필 이미지 URL |
|
|
공지글 여부 |
|
|
생성 일시 |
|
|
포스트 포토(URL 포함) 데이터를 담은 객체 배열 |
|
|
포토 id |
|
|
포스트 내 포토의 순서 |
|
|
포스트 포토 url |
|
|
포스트 뷰 페이지네이션 정보를 담은 Pageable 객체 |
|
|
현재 페이지 번호 |
|
|
한 페이지에 포함되는 항목의 수 |
|
|
정렬 정보 |
|
|
정렬 조건이 없는지 여부 |
|
|
정렬되지 않았는지 여부 |
|
|
정렬되었는지 여부 |
|
|
페이징된 항목의 시작 위치 |
|
|
페이징된 요청인지 여부 |
|
|
페이징되지 않은 요청인지 여부 |
|
|
한 페이지에 포함되는 항목의 수 |
|
|
현재 페이지 번호 |
|
|
정렬 정보 |
|
|
정렬 조건이 없는지 여부 |
|
|
정렬되지 않았는지 여부 |
|
|
정렬되었는지 여부 |
|
|
현재 페이지에 있는 요소의 수 |
|
|
이 페이지가 첫 번째 페이지인지 여부 |
|
|
이 페이지가 마지막 페이지인지 여부 |
|
|
페이지가 비어있는지 여부 |
챌린지 포스트 생성
경로 변수로 받은 challenge의 id값에 해당하는 챌린지에 포스트를 작성합니다. 챌린지의 호스트라면 공지 포스트를 작성할 수 있습니다.
HTTP request
POST /api/challenges/1/posts HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer ACCESS_TOKEN
Content-Length: 176
Host: localhost:8080
{
"content" : "I want to create this post.",
"isAnnouncement" : false,
"photos" : [ {
"viewOrder" : 1,
"imageExtension" : "jpg",
"contentLength" : 100
} ]
}
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 124
{
"message" : "정상적으로 포스트를 생성했습니다.",
"data" : [ "https://please.upload/your-photo/here" ]
}
Request fields
Path | Type | Description |
---|---|---|
|
|
포스트 내용 |
|
|
공지 포스트 여부 |
|
|
첨부한 이미지 파일 목록 |
|
|
첨부한 이미지 파일의 포스트 내 정렬 순서 |
|
|
첨부한 이미지 파일의 확장자명 |
|
|
첨부한 이미지 파일의 길이 |
Response fields
Path | Type | Description |
---|---|---|
|
|
메시지 |
|
|
AWS S3 업로드를 위한 preSignedUrl List<String> |
에러 응답
중도 포기한 경우 (403 Forbidden)
챌린지를 중도 포기한 이후 게시물을 생성할 수 없습니다.
HTTP request
POST /api/challenges/1/posts HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer ACCESS_TOKEN
Content-Length: 176
Host: localhost:8080
{
"content" : "I want to create this post.",
"isAnnouncement" : false,
"photos" : [ {
"viewOrder" : 1,
"imageExtension" : "jpg",
"contentLength" : 100
} ]
}
HTTP response
HTTP/1.1 403 Forbidden
Content-Type: application/json;charset=UTF-8
Content-Length: 150
{
"code" : "POST_CREATION_FORBIDDEN_DUE_TO_GIVE_UP",
"message" : "챌린지 중도 포기 이후에는 게시물을 생성할 수 없습니다."
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
챌린지 포스트 수정
경로 변수로 받은 post의 id값에 해당하는 포스트를 수정합니다. 수정은 포스트 내용 변경, 공지 포스트 여부 변경과 함께 포스트 내 이미지 파일의 추가, 삭제 및 정렬 순서 변경을 포함합니다.
HTTP request
PATCH /api/challenges/1/posts/1 HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer ACCESS_TOKEN
Content-Length: 281
Host: localhost:8080
{
"content" : "I want to patch this to post.",
"isAnnouncement" : false,
"newPhotos" : [ {
"viewOrder" : 2,
"imageExtension" : "jpg",
"contentLength" : 100
} ],
"modifiedPhotos" : [ {
"photoId" : 3,
"viewOrder" : 1
} ],
"deletedPhotoIds" : [ 1 ]
}
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 124
{
"message" : "정상적으로 포스트를 수정했습니다.",
"data" : [ "https://please.upload/your-photo/here" ]
}
Request fields
Path | Type | Description |
---|---|---|
|
|
포스트 수정 내용 |
|
|
공지 포스트 여부 |
|
|
새로 첨부한 이미지 파일 목록 |
|
|
첨부한 이미지 파일의 포스트 내 정렬 순서 |
|
|
첨부한 이미지 파일의 확장자명 |
|
|
첨부한 이미지 파일의 길이 |
|
|
포스트 내 정렬 순서가 변경된 이미지 파일 목록 |
|
|
정렬 순서를 변경하려는 이미지 파일의 PostPhotoId |
|
|
변경하려는 정렬 순서 |
|
|
삭제할 이미지 파일 PostPhotoId List<Long> |
Response fields
Path | Type | Description |
---|---|---|
|
|
메시지 |
|
|
AWS S3 업로드를 위한 preSignedUrl List<String> |
에러 응답
중도 포기한 경우 (403 Forbidden)
챌린지를 중도 포기한 이후 게시물을 수정할 수 없습니다.
HTTP request
PATCH /api/challenges/1/posts/1 HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer ACCESS_TOKEN
Content-Length: 176
Host: localhost:8080
{
"content" : "I want to create this post.",
"isAnnouncement" : false,
"photos" : [ {
"viewOrder" : 1,
"imageExtension" : "jpg",
"contentLength" : 100
} ]
}
HTTP response
HTTP/1.1 403 Forbidden
Content-Type: application/json;charset=UTF-8
Content-Length: 154
{
"code" : "POST_MODIFICATION_FORBIDDEN_DUE_TO_GIVE_UP",
"message" : "챌린지 중도 포기 이후에는 게시물을 수정할 수 없습니다."
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
챌린지 포스트 삭제
경로 변수로 받은 post의 id값에 해당하는 포스트를 삭제합니다. 사실 일반 포스트는 삭제 기능을 제공하지 않기 때문에, 요청을 보내더라도 예외 처리됩니다. 공지 포스트만 챌린지 호스트가 삭제할 수 있습니다.
HTTP request
DELETE /api/challenges/1/posts/1 HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 85
{
"message" : "정상적으로 포스트를 삭제했습니다.",
"data" : null
}
Response fields
Path | Type | Description |
---|---|---|
|
|
메시지 |
|
|
삭제된 포스트 id |
에러 응답
중도 포기한 경우 (403 Forbidden)
챌린지를 중도 포기한 이후 게시물을 삭제할 수 없습니다.
HTTP request
DELETE /api/challenges/1/posts/1 HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
HTTP response
HTTP/1.1 403 Forbidden
Content-Type: application/json;charset=UTF-8
Content-Length: 150
{
"code" : "POST_DELETION_FORBIDDEN_DUE_TO_GIVE_UP",
"message" : "챌린지 중도 포기 이후에는 게시물을 삭제할 수 없습니다."
}
Response fields
Path | Type | Description |
---|---|---|
|
|
오류 응답 코드 |
|
|
오류 메세지 |
리프레시 토큰 API
클라이언트가 토큰 리프레시를 요청하면, 새로운 액세스 토큰과 리프레스 토큰을 발급합니다.
보통 액세스 토큰 만료될 경우 요청이 발생하기 때문에, 다른 대부분의 요청과 달리 Request Header에 액세스 토큰을 담아 보낼 필요가 없습니다.
토큰 리프레시 요청
백엔드 URL에 요청을 보냈으나 401 Unauthorized 상태 코드를 받았다면, 액세스 토큰이 만료되는 등 더 이상 사용할 수 없다는 의미입니다.
그 경우 "/api/token" 경로를 통해 토큰 재발급을 요청해야 합니다. (401 이외의 상태 코드로는 토큰 재발급을 요청할 수 없습니다.)
리프레시 토큰은 이미 쿠키에 세팅되어 요청에 담기기 때문에, 추가로 보내야 할 값은 없습니다.
다만 표준 CORS 요청은 기본적으로 쿠키를 포함한 인증 정보를 설정할 수 없습니다. 그렇기 때문에 인증 정보(쿠키 등)를 요청에 추가하도록 수동으로 "withCredentials: true" 설정을 추가해야 합니다.
(이는 백엔드에서 쿠키를 포함한 응답을 보낼 때 "Access-Control-Allow-Credentials" 설정을 "true"로 하는 이유와 동일합니다.)
리프레시 토큰이 유효하고 적절하다면 새로운 액세스 토큰은 응답 본문에, 새로운 리프레시 토큰은 쿠키에 담아 재발급합니다.
HTTP request
POST /api/token HTTP/1.1
Host: localhost:8080
Cookie: refresh=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0In0.DUMMY_SIGNATURE2
Content-Type: application/x-www-form-urlencoded
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 265
{
"message" : "새로운 액세스 토큰 및 리프레시 토큰이 성공적으로 발급되었습니다.",
"data" : {
"accessToken" : "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0In0.DUMMY_SIGNATURE1",
"tokenType" : "Bearer",
"expiresIn" : 1800000
}
}
Response fields
Path | Type | Description |
---|---|---|
|
|
메시지 |
|
|
새로 발급한 액세스 토큰 |
|
|
발급한 토큰의 유형. "Bearer" |
|
|
액세스 토큰의 유효 기간 |
토큰 리프레시 실패 : 400 Bad Request
토큰 리프레시 요청 시 파라미터 값이 비어있거나 지원하는 않는 값 등 잘못된 요청일 경우 발생합니다.
HTTP request
POST /api/token HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
HTTP response
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Content-Length: 57
{
"code" : "BAD_REQUEST",
"message" : "Bad Request"
}
Response fields
Path | Type | Description |
---|---|---|
|
|
에러 코드 |
|
|
에러 메시지 |
토큰 리프레시 실패 : 401 Unauthorized
토큰이 만료되거나 값이 변형되는 등 정상적으로 사용할 수 없는 토큰일 경우 발생합니다.
토큰 리프레시 요청 시 이 응답을 받았다면 리프레시 토큰이 만료되었을 가능성이 큽니다. 이 경우 재로그인이 필요합니다.
HTTP request
POST /api/token HTTP/1.1
Host: localhost:8080
Cookie: refresh=expiredGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0In0.DUMMY_SIGNATURE2
Content-Type: application/x-www-form-urlencoded
HTTP response
HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=UTF-8
Content-Length: 60
{
"code" : "UNAUTHORIZED",
"message" : "Invalid token"
}
Response fields
Path | Type | Description |
---|---|---|
|
|
에러 코드 |
|
|
에러 메시지 |
토큰 리프레시 실패 : 403 Forbidden
토큰이 제공하는 권한보다 더 높은 권한을 요구할 때 발생합니다. 예를 들면 일반 사용자가 관리자 페이지에 접근하는 경우를 들 수 있습니다.
해빗페이에서 권한 문제가 발생하는 대상은 액세스 토큰이기 때문에, 액세스 토큰의 권한이 부족할 때 발생하는 상태 코드로 이해하면 되겠습니다.
HTTP request
POST /api/token HTTP/1.1
Host: localhost:8080
Cookie: refresh=justGuestGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0In0.DUMMY_SIGNATURE2
Content-Type: application/x-www-form-urlencoded
HTTP response
HTTP/1.1 403 Forbidden
Content-Type: application/json;charset=UTF-8
Content-Length: 75
{
"code" : "FORBIDDEN",
"message" : "Not Allowed to Access or Modify"
}
Response fields
Path | Type | Description |
---|---|---|
|
|
에러 코드 |
|
|
에러 메시지 |
챌린지 벌금 API
챌린지 내 벌금 현황을 조회할 수 있습니다.
Request Header 에는 Authorization: Bearer {access token}
와 같은 형식으로 보내야 하며, 사용자의 액세스 토큰
이 필요합니다.
챌린지 내 벌금 현황 조회
경로 변수로 받은 challenge id 값으로 챌린지를 특정합니다.
벌금 현황 페이지에서 바로 사용할 수 있도록, '챌린지 내 전체 누적 벌금 총합’과 ''나’의 누적 벌금 총합' 속성을 따로 제공합니다.
챌린지 내 전체 멤버를 대상으로 한 { 닉네임, 누적 벌금액, 달성률 } 목록이 있습니다. 이때 전체 멤버에는 '나’가 포함됩니다.
정렬은 따로 되어있지 않습니다.
HTTP request
GET /api/challenges/1/fee HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Host: localhost:8080
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 333
{
"message" : "",
"data" : {
"totalFee" : 1500,
"myFee" : 500,
"memberFeeList" : [ {
"nickname" : "testUser",
"totalFee" : 1000,
"completionRate" : 10,
"isMe" : true
}, {
"nickname" : "selfUser",
"totalFee" : 500,
"completionRate" : 20,
"isMe" : false
} ]
}
}
Response fields
Path | Type | Description |
---|---|---|
|
|
메시지 |
|
|
챌린지 내 전체 누적 벌금 총합 |
|
|
챌린지 내 나의 누적 벌금 총합 |
|
|
챌린지 내 멤버별 벌금 현황 목록 |
|
|
멤버 닉네임 |
|
|
챌린지 내 멤버의 누적 벌금 총합 |
|
|
챌린지 내 멤버의 달성률 |
|
|
나의 벌금 현황 여부 |