-
Notifications
You must be signed in to change notification settings - Fork 0
V1 Group API
모임에서 사용할 이미지를 사전에 업로드하는 API입니다.업로드된 이미지는 서버에서 리사이즈/변환된 뒤, 각 사이즈별 이미지 URL 목록을 반환합니다.
이 URL 정보는 이후 모임 생성(POST /api/v1/groups/create)에서 images 필드로 함께 전송하여 사용합니다.
Headers
Authorization: Bearer {accessToken}Content-Type: multipart/form-data
Body (multipart/form-data)
-
images(File[], required)- 업로드할 이미지 파일 배열
- 필드 이름은 반드시
images로 전송해야 합니다. - 여러 장을 업로드할 때는 같은 키(
images)로 파일을 여러 개 전송합니다. - 권장 개수: 모임에서 사용하는 이미지가 최대 3장이므로, 이 API에서도 최대 3장 업로드를 기준으로 사용하면 좋습니다.
- 지원 포맷 예:
image/jpeg,image/png등 일반적인 이미지 포맷(서버에서 webp 등으로 변환된 URL을 내려줄 수 있습니다)
예시 요청
POST https://{baseUrl}/api/v1/groups/images/upload
Authorization: Bearer {accessToken}
Content-Type: multipart/form-data
(images: 파일 1~3개){
"status": 201,
"success": true,
"data": {
"images": [
{
"sortOrder": 0,
"imageUrl440x240": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211100439_0_4a9f6714-278c-466e-acb9-5122a855cf75_440x240.webp",
"imageUrl100x100": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211100439_0_4a9f6714-278c-466e-acb9-5122a855cf75_100x100.webp"
},
{
"sortOrder": 1,
"imageUrl440x240": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211100440_1_a5ba4d02-8ca1-4b8f-9ca6-fa7d6d2f2399_440x240.webp",
"imageUrl100x100": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211100440_1_a5ba4d02-8ca1-4b8f-9ca6-fa7d6d2f2399_100x100.webp"
}
]
}
}상위 공통 응답
-
status(Number): HTTP 상태 코드 숫자값 (예: 201, 200 등) -
success(Boolean): 요청 성공 여부 -
data(Object): 실제 응답 데이터가 담기는 영역
data.images (PreUploadGroupImageResponse)
-
images(PreUploadGroupImageItemResponse[]): 업로드된 각 이미지에 대한 정보 목록- 각 아이템(
PreUploadGroupImageItemResponse)은 다음과 같습니다.
- 각 아이템(
-
sortOrder(Number): 이미지 정렬 순서- 0부터 시작하는 인덱스로, 업로드한 순서대로 0, 1, 2 … 형태로 부여됩니다.
- 이후 모임 생성 시, 이 순서를 기반으로 대표/서브 이미지를 판단할 수 있습니다.
-
imageUrl440x240(String): 440x240 크기로 리사이즈된 이미지 URL- 목록/카드형 UI에서 썸네일로 사용하기 좋은 사이즈
-
imageUrl100x100(String): 100x100 크기로 리사이즈된 이미지 URL- 작은 썸네일, 프로필 등으로 사용할 수 있는 사이즈
-
모임 생성 전에 반드시 거치는 “사전 업로드” 단계
이 API는 이미지를 실제 모임에 연결하지 않고, 단순히 “업로드 + URL 생성”만 담당합니다.응답으로 받은
images[].imageUrl440x240,images[].imageUrl100x100,sortOrder값들을 사용해 이후POST /api/v1/groups/create호출 시images필드를 구성하게 됩니다. -
multipart/form-data 기반 파일 업로드 전용 API
본 API는 오직 이미지 파일 업로드만 받으며, 별도의 JSON 본문은 없습니다. 프론트에서는
<input type="file" multiple>또는 FormData를 사용해images필드에 파일들을 넣어 전송하면 됩니다. -
서버에서 리사이즈/포맷 변환을 처리
클라이언트는 원본 이미지만 업로드하면 되고, 서버가 리사이즈된 이미지(440x240, 100x100)를 생성한 뒤 URL로 내려줍니다. 응답 URL의 실제 포맷(webp 등)은 서버 설정에 따라 달라질 수 있으며, 프론트는 “단순히 URL을 이미지 경로로 사용한다”는 관점으로만 이해하면 됩니다.
-
정렬 순서가 0부터 시작
sortOrder값이 0, 1, 2 … 로 내려오므로, 프론트에서 첫 번째 이미지를 대표 이미지로 사용하고 싶다면sortOrder == 0인 이미지를 대표로 쓰면 됩니다. -
인증이 필요한 업로드 API
@AuthenticationPrincipal을 사용하고 있어, 실제로는 로그인한 사용자만 호출 가능하도록 보안이 걸려 있습니다. 현재 구현에서는 업로드 시점에 사용자만 호출 하되 정보를 직접 사용하지 않습니다. 추후 “누가 올린 이미지인지” 추적하거나, 악성 업로드 방지 정책 등을 적용하기 위한 기반이 됩니다.
새로운 모임을 생성합니다. 로그인한 유저가 모임의 **호스트(생성자)**가 되며, 생성 시점에 호스트는 자동으로 모임 참여자로 포함됩니다.
이전 버전과 달리, 이 API는 multipart/form-data가 아닌 순수 application/json 형태로 요청을 받습니다.
이미지는 별도의 API(/api/v1/groups/images/upload)로 사전 업로드 후, 그 정보를 images 필드로 함께 전송하는 방식입니다.
Headers
Authorization: Bearer {accessToken}Content-Type: application/json
Body (JSON)
{
"title": "강남에서 하는 자바 스터디",
"location": "서울 강남구",
"locationDetail": "강남역 2번 출구 근처 카페",
"startTime": "2025-12-10T19:00:00",
"endTime": "2025-12-10T21:00:00",
"tags": [
"자바",
"백엔드",
"스터디"
],
"description": "자바 백엔드 신입 준비하는 분들을 위한 스터디입니다.",
"maxParticipants": 10,
"images": [
{
"sortOrder": 0,
"imageUrl440x240": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251212140620_0_ef327e02-a1a8-4f97-870c-05daba07f107_440x240.webp",
"imageUrl100x100": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251212140620_0_ef327e02-a1a8-4f97-870c-05daba07f107_100x100.webp"
},
{
"sortOrder": 1,
"imageUrl440x240": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251212140620_1_274b5f88-73ad-4cce-b907-f8c179476d05_440x240.webp",
"imageUrl100x100": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251212140620_1_274b5f88-73ad-4cce-b907-f8c179476d05_100x100.webp"
}
]
}필드 설명 (CreateGroupRequest)
-
title(String, required)- 모임 제목
- 공백 문자열 불가 (
@NotBlank)
-
location(String, required)- 모임 기본 위치 정보 (예: "서울 강남구")
- 공백 문자열 불가 (
@NotBlank)
-
locationDetail(String, optional)- 모임 상세 위치 정보 (예: "강남역 2번 출구 근처 카페")
- 상세 주소/장소 설명, 없으면
null또는 생략 가능
-
startTime(String, required, ISO 8601 형식)- 모임 시작 일시
- 내부적으로
LocalDateTime으로 파싱 -
현재 시각 이후만 허용
-
@FutureOrPresent적용 - 예:
"2025-12-10T19:00:00"
-
-
endTime(String, optional, ISO 8601 형식)- 모임 종료 일시
- 내부적으로
LocalDateTime으로 파싱 - 값이 존재한다면 항상 현재 시각 이후여야 함 (
@Future) - 비워둘 수도 있으나, 비즈니스 규칙에 따라 서비스에서 추가 검증 가능
-
tags(String[], optional)- 모임 태그 목록
- 예:
["자바", "백엔드", "스터디"] - 없으면
null또는 빈 배열 가능
-
description(String, required)- 모임 상세 설명
- 공백 문자열 불가 (
@NotBlank)
-
maxParticipants(Number, required)- 최대 참여 인원
- 최소 2명, 최대 12명 사이의 정수만 허용
-
@Min(2),@Max(12)
-
- 예:
10
-
images(CreateGroupImageRequest[], optional)- 모임에 연결할 이미지 정보 목록
- 각 원소는
CreateGroupImageRequest구조이며, 이미지 업로드/관리 규칙은 “그룹 이미지 API” 명세에서 함께 정의됩니다. - 사전 업로드 API(
/api/v1/groups/images/upload)에서 받은 결과를 기반으로 구성
{
"success": true,
"data": {
"id": 6,
"title": "강남에서 하는 자바 스터디",
"location": "서울 강남구",
"locationDetail": "강남역 2번 출구 근처 카페",
"startTime": "2025-12-10T19:00:00",
"endTime": "2025-12-10T21:00:00",
"tags": [
"자바",
"백엔드",
"스터디"
],
"description": "자바 백엔드 신입 준비하는 분들을 위한 스터디입니다.",
"participantCount": 1,
"maxParticipants": 10,
"createdBy": {
"userId": 1,
"nickName": "코딩하는두더지",
"profileImage": "https://cdn.example.com/profiles/1/profile.png",
"profileMessage": "추가한내용"
},
"createdAt": "2025-12-02T14:29:06",
"updatedAt": "2025-12-02T14:29:06",
"images": [
{
"sortOrder": 0,
"imageUrl440x240": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251212140620_0_ef327e02-a1a8-4f97-870c-05daba07f107_440x240.webp",
"imageUrl100x100": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251212140620_0_ef327e02-a1a8-4f97-870c-05daba07f107_100x100.webp"
},
{
"sortOrder": 1,
"imageUrl440x240": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251212140620_1_274b5f88-73ad-4cce-b907-f8c179476d05_440x240.webp",
"imageUrl100x100": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251212140620_1_274b5f88-73ad-4cce-b907-f8c179476d05_100x100.webp"
}
]
}
}
⚠️ 위images예시는PreUploadGroupImageItemResponse/GroupImageItemResponse와 동일한 구조를 기준으로 작성했습니다. 실제 필드 정의는 하단 “그룹 이미지 API” 및 DTO 정의와 함께 맞춰서 사용하면 됩니다.
필드 설명 (CreateGroupResponse)
-
success: API 응답 성공 여부 (true/false) -
data.id(Number)- 생성된 모임의 식별 ID
-
data.title(String)- 모임 제목
-
data.location/data.locationDetail(String)- 모임 기본/상세 위치 정보
-
data.startTime/data.endTime(String, ISO 8601)- 모임 시작/종료 일시
- 서버 내부에서는
LocalDateTime으로 관리되며, 응답 시 문자열로 직렬화됨 - 예:
"2025-12-10T19:00:00"
-
data.tags(String[])- 태그 이름 목록
- 서버에서는
GroupTag→Tag엔티티를 통해 태그 이름만 추출하여 반환
-
data.description(String)- 모임 상세 설명
-
data.participantCount(Number)- 현재 참여 상태(ATTEND) 인 인원 수
- 생성 직후에는 최소 1명(호스트 본인)이 포함됩니다.
-
data.maxParticipants(Number)- 모임 최대 참여 인원
-
data.createdBy(Object)- 모임 생성자(호스트) 정보
-
userId: 생성자 ID -
nickName: 생성자 닉네임 -
profileImage: 생성자 프로필 이미지 URL (null이면 기본 이미지 또는 없음) -
profileMessage: 생성자 프로필 메시지
-
data.createdAt/data.updatedAt(String, ISO 8601)- 모임 생성/수정 시각
- 예:
"2025-12-02T14:29:06"
-
data.images(GroupImageItemResponse[])- 모임에 연결된 이미지 정보 목록
- 각 요소(이미지 1장)에 대한 필드 예시:
-
sortOrder(Number): 이미지 정렬 순서 (1부터 시작) -
imageUrl440x240(String): 440x240 사이즈 썸네일 이미지 URL -
imageUrl100x100(String): 100x100 사이즈 썸네일 이미지 URL
-
- 실제 구조는
GroupImageItemResponse/PreUploadGroupImageItemResponse와 동일하게 사용
-
요청 형식 변경 (multipart → JSON)
- 이전 버전에서는
multipart/form-data로request+images파일을 함께 보내야 했지만, 현재 버전은application/json만 사용합니다. - 이미지는
/api/v1/groups/images/uploadAPI로 먼저 업로드 후, 그 결과를images필드에 담아 모임 생성 시 함께 보내는 구조입니다.
- 이전 버전에서는
-
시간 검증 로직이 명확함
-
startTime은 현재 시각과 같거나 이후만 허용 -
endTime은 값이 있을 경우 현재 시각 이후만 허용 - 실제 비즈니스에서는
endTime > startTime등의 추가 검증도 서비스 레이어에서 처리할 수 있습니다.
-
-
참여 인원/호스트 처리 방식
- 모임 생성 시, 요청 보낸 유저(
CustomUserDetails)가 자동으로 호스트 + 첫 참여자가 됩니다. -
participantCount는GroupUserStatus.ATTEND인 유저 수만 카운트하며, 생성 직후 기본적으로 1명이 됩니다.
- 모임 생성 시, 요청 보낸 유저(
-
태그와 이미지가 전부 “연결 정보”로 관리됨
- 태그는
GroupTag–Tag엔티티를 통해 관리되며, 응답에서는 이름(String) 리스트만 내려줍니다. - 이미지는 그룹 이미지 도메인(
GroupImageService)에서 관리되며, 모임 생성 시에는 사전 업로드 결과를 연결하는 역할만 수행합니다.
- 태그는
-
검증 조건이 강하게 잡혀 있음
- 제목/위치/설명은 모두
@NotBlank로 공백 방지 - 최대 인원은 2~12명으로 제한해 모임 규모를 명확히 제어
- 잘못된 값 입력 시, Spring Validation 에러 응답이 반환됩니다.
- 제목/위치/설명은 모두
특정 모임에 현재 로그인한 사용자를 참여자로 추가합니다. 요청 성공 시, 최신 모임 정보(참여 인원, 참여자 목록, 내 참여 상태 등)를 함께 반환합니다. 로그인한 사용자만 호출할 수 있습니다.
Path Parameter
-
groupId(Number, required): 참여할 모임 ID
Headers
Authorization: Bearer {accessToken}Content-Type: application/json
Body
- No Required Request Body
Example Endpoint
POST https://{baseUrl}/api/v1/groups/1/attend
Authorization: Bearer {accessToken}
Content-Type: application/json{
"status": 200,
"success": true,
"data": {
"id": 1,
"title": "참여 테스트용 자바 스터디",
"location": "서울 강남구",
"locationDetail": "강남역 2번 출구 근처 카페",
"startTime": "2026-12-10T19:00:00",
"endTime": "2026-12-10T21:00:00",
"images": [
{
"sortOrder": 0,
"imageId440x240": 1,
"imageId100x100": 2,
"imageUrl440x240": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211101457_0_c98a6fef-da17-4ad9-a2b5-dde824cd067f_440x240.webp",
"imageUrl100x100": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211101457_0_c98a6fef-da17-4ad9-a2b5-dde824cd067f_100x100.webp"
},
{
"sortOrder": 1,
"imageId440x240": 3,
"imageId100x100": 4,
"imageUrl440x240": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211101458_1_5a5754d4-6e83-4e11-88af-ec72d7cc89ff_440x240.webp",
"imageUrl100x100": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211101458_1_5a5754d4-6e83-4e11-88af-ec72d7cc89ff_100x100.webp"
}
],
"tags": [
"참여테스트",
"자바",
"백엔드"
],
"description": "MEMBER들이 참석/중복 참석 예외를 테스트하기 위한 모임입니다.",
"participantCount": 2,
"maxParticipants": 5,
"createdBy": {
"userId": 1,
"nickName": "HostUser",
"profileImage": null,
"profileMessage": "추가한내용"
},
"createdAt": "2025-12-11T10:14:59.324442",
"updatedAt": "2025-12-11T10:14:59.324442",
"userStatus": {
"isJoined": true,
"joinedAt": "2025-12-11T10:15:03.4922073"
},
"joinedMembers": [
{
"userId": 1,
"groupRole": "HOST",
"nickName": "HostUser",
"profileImage": null,
"joinedAt": "2025-12-11T10:14:59.336343"
},
{
"userId": 2,
"groupRole": "MEMBER",
"nickName": "MemberOne",
"profileImage": null,
"joinedAt": "2025-12-11T10:15:03.4922073"
}
]
}
}상위 공통 응답
-
status(Number): HTTP 상태 코드 숫자값 (예: 200, 201) -
success(Boolean): 요청 성공 여부 -
data(Object): 모임 상세 정보
data (모임 정보)
-
id(Number): 모임 ID -
title(String): 모임 제목 -
location(String): 모임 기본 위치 정보 -
locationDetail(String): 모임 상세 위치 정보- 없을 수 있음
-
startTime(String, ISO 8601): 모임 시작 일시- 예:
"2026-12-10T19:00:00"
- 예:
-
endTime(String, ISO 8601): 모임 종료 일시- 예:
"2026-12-10T21:00:00"
- 예:
-
images(GroupImageItemResponse[]): 모임에 연결된 이미지 목록- 각 아이템:
-
sortOrder(Number): 이미지 노출 순서 (0부터 시작) -
imageId440x240(Number): 440x240 사이즈 이미지 리소스 ID -
imageId100x100(Number): 100x100 사이즈 이미지 리소스 ID -
imageUrl440x240(String): 440x240 크기 이미지 URL -
imageUrl100x100(String): 100x100 크기 이미지 URL
-
- 각 아이템:
-
tags(String[]): 모임 태그 목록 (예:["참여테스트", "자바", "백엔드"]) -
description(String): 모임 상세 설명 -
participantCount(Number): 현재 참여 인원 수 -
maxParticipants(Number): 최대 참여 인원 수 -
createdBy(Object): 모임 생성자 정보-
userId(Number): 생성자 유저 ID -
nickName(String): 생성자 닉네임 -
profileImage(String or null): 생성자 프로필 이미지 URL -
profileMessage: 생성자 프로필 메시지
-
-
createdAt(String, ISO 8601)- 모임 생성 일시
- 예:
"2025-12-11T10:14:59.324442"
-
updatedAt(String, ISO 8601)- 모임 수정 일시
- 예:
"2025-12-13T10:14:59.324442"
-
userStatus(Object): 현재 로그인한 유저 기준의 모임 참여 상태-
isJoined(Boolean): 참여 여부-
true면 현재 이 모임에 참여 중
-
-
joinedAt(String or null, ISO 8601):이 유저가 이 모임에 참여한 시각- 참여하지 않은 경우
null
- 참여하지 않은 경우
-
-
joinedMembers(JoinedMemberResponse[]): 모임에 참여 중인 모든 사용자 목록- 각 아이템:
-
userId(Number): 참여자 유저 ID -
groupRole(String): 모임 내 역할- 예:
"HOST","MEMBER"
- 예:
-
nickName(String): 참여자 닉네임 -
profileImage(String or null): 참여자 프로필 이미지 URL -
joinedAt(String, ISO 8601): 이 유저가 이 모임에 참여한 시각
-
- 각 아이템:
-
로그인 필수 API
-
@AuthenticationPrincipal을 사용하므로, 반드시Authorization: Bearer {accessToken}헤더가 있어야 합니다. - 비로그인 사용자는 호출할 수 없습니다.
-
-
상태 변경 + 즉시 조회를 한 번에 수행
- 이 API는 단순히 “참여 완료”만 응답하는 것이 아니라, 참여 처리 이후의 최신 모임 상세 정보를 그대로 반환합니다.
- 프론트는 응답의
data를 그대로 화면 상태에 반영하면 됩니다.
-
내 참여 상태와 전체 참여자 목록을 함께 제공
-
userStatus에서 현재 로그인한 내 참여 여부/참여 시각을 확인할 수 있고, -
joinedMembers에서 호스트/멤버 전체 목록과 각자의 역할을 한 번에 확인할 수 있습니다. - 참여/취소 이후 UI를 갱신하기에 적합한 형태입니다.
-
특정 모임에 대한 현재 로그인한 사용자의 참여를 취소합니다.요청 성공 시, 마찬가지로 최신 모임 정보(참여 인원, 참여자 목록, 내 참여 상태 등)를 반환합니다. 로그인한 사용자만 호출할 수 있습니다.
Path Parameter
-
groupId(Number, required): 참여를 취소할 모임 ID
Headers
Authorization: Bearer {accessToken}Content-Type: application/json
Body
- No Required Request Body
Example Endpoint
POST https://{baseUrl}/api/v1/groups/1/cancel
Authorization: Bearer {accessToken}
Content-Type: application/json- Response 구조는 **
/api/v1/groups/{groupId}/attend와 동일한GetGroupResponse**를 사용합니다. - 차이점은, 참여 취소 이후에는
-
participantCount값이 줄어들고, -
joinedMembers목록에서 해당 사용자가 제외되거나, -
userStatus.isJoined가false,joinedAt이null로 바뀌는 식으로 “참여하지 않은 상태”가 반영된 최신 그룹 정보가 내려온다는 점입니다.
-
(구체적인 값은 비즈니스 로직에 따라 달라질 수 있으므로, 여기서는 구조만 동일하다고 명시합니다.)
-
로그인 필수 + 자기 자신만 취소 가능
-
Authorization헤더가 필요하며, 내부적으로는 “현재 로그인한 사용자” 기준으로만 참여 취소가 수행됩니다.
-
-
참여 취소 후에도 동일한 구조의 그룹 상세 정보 반환
- 프론트는
attend/cancel모두 응답 타입이 같기 때문에, 두 API 호출 후의 후처리를 공통 로직으로 묶어서 사용할 수 있습니다.
- 프론트는
-
참여 상태 토글 패턴의 한 축
- UI 상에서는 하나의 “참여/취소” 버튼을 두고,
userStatus.isJoined에 따라-
false→/attend호출 -
true→/cancel호출 같은 방식으로 쉽게 토글 로직을 구현할 수 있습니다.
-
- UI 상에서는 하나의 “참여/취소” 버튼을 두고,
특정 모임의 상세 정보를 조회합니다. 로그인 여부에 따라 userStatus(내 참여 여부/참여 시간)가 달라지며, 항상 joinedMembers(참여자 목록)는 함께 내려옵니다.
- 비로그인 사용자는 모임 정보 + 참여자 목록만 조회
- 로그인 사용자는 **추가로 내 참여 상태(
userStatus)**도 함께 조회
Path Parameter
-
groupId(Number, required): 상세 조회할 모임 ID
Headers
-
Authorization: Bearer {accessToken}(optional)- 로그인한 상태에서 내 참여 여부까지 보고 싶을 때 사용
- 없으면 비로그인 사용자로 처리됨
Body
- No Required Request Body
Example Endpoint
GET https://{baseUrl}/api/v1/groups/1
Authorization: Bearer {accessToken}또는 비로그인 조회:
GET https://{baseUrl}/api/v1/groups/1{
"status": 200,
"success": true,
"data": {
"id": 1,
"title": "참여 취소 테스트용 자바 스터디",
"location": "서울 서초구",
"locationDetail": "교대역 1번 출구 근처 카페",
"startTime": "2025-12-11T19:00:00",
"endTime": "2025-12-11T21:00:00",
"images": [
{
"sortOrder": 0,
"imageId440x240": 1,
"imageId100x100": 2,
"imageUrl440x240": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211102446_0_3dfb1903-6cdb-462a-ad87-7f841a162881_440x240.webp",
"imageUrl100x100": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211102446_0_3dfb1903-6cdb-462a-ad87-7f841a162881_100x100.webp"
},
{
"sortOrder": 1,
"imageId440x240": 3,
"imageId100x100": 4,
"imageUrl440x240": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211102447_1_637526a8-d121-4dfc-b34a-4d8cb90b6283_440x240.webp",
"imageUrl100x100": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211102447_1_637526a8-d121-4dfc-b34a-4d8cb90b6283_100x100.webp"
}
],
"tags": [
"참여취소테스트",
"자바"
],
"description": "참여 취소/중복 취소/HOST 취소 예외를 테스트하는 모임입니다.",
"participantCount": 3,
"maxParticipants": 5,
"createdBy": {
"userId": 1,
"nickName": "HostTwo",
"profileImage": null,
"profileMessage": "추가한내용"
},
"createdAt": "2025-12-11T10:24:48.20504",
"updatedAt": "2025-12-11T10:24:48.20504",
"userStatus": {
"isJoined": true,
"joinedAt": "2025-12-11T10:25:15.235481"
},
"joinedMembers": [
{
"userId": 1,
"groupRole": "HOST",
"nickName": "HostTwo",
"profileImage": null,
"joinedAt": "2025-12-11T10:24:48.214915"
},
{
"userId": 2,
"groupRole": "MEMBER",
"nickName": "CancelMember1",
"profileImage": null,
"joinedAt": "2025-12-11T10:25:14.411513"
},
{
"userId": 3,
"groupRole": "MEMBER",
"nickName": "CancelMember2",
"profileImage": null,
"joinedAt": "2025-12-11T10:25:15.235481"
}
]
}
}상위 공통 응답
-
status(Number): HTTP 상태 코드 숫자값 (예: 200, 201) -
success(Boolean): 요청 성공 여부 -
data(Object): 모임 상세 정보
data (모임 정보)
-
id(Number): 모임 ID -
title(String): 모임 제목 -
location(String): 모임 기본 위치 정보 -
locationDetail(String): 모임 상세 위치 정보- 없을 수 있음
-
startTime(String, ISO 8601): 모임 시작 일시- 예:
"2025-12-11T19:00:00"
- 예:
-
endTime(String, ISO 8601): 모임 종료 일시- 예:
"2025-12-11T21:00:00"
- 예:
-
images(GroupImageItemResponse[]): 모임에 연결된 이미지 목록- 각 아이템:
-
sortOrder(Number): 이미지 노출 순서 (0부터 시작, 0이 대표 이미지) -
imageId440x240(Number): 440x240 사이즈 이미지 리소스 ID -
imageId100x100(Number): 100x100 사이즈 이미지 리소스 ID -
imageUrl440x240(String): 440x240 크기 이미지 URL -
imageUrl100x100(String): 100x100 크기 이미지 URL
-
- 각 아이템:
-
tags(String[]): 모임 태그 목록 (예:["참여취소테스트", "자바"]) -
description(String): 모임 상세 설명 -
participantCount(Number): 현재 참여 인원 수 -
maxParticipants(Number): 최대 참여 인원 수 -
createdBy(Object): 모임 생성자 정보-
userId(Number): 생성자 유저 ID -
nickName(String): 생성자 닉네임 -
profileImage(String or null): 생성자 프로필 이미지 URL -
profileMessage: 생성자 프로필 메시지
-
-
createdAt(String, ISO 8601): 모임 생성 일시- 예:
"2025-12-11T10:24:48.20504"
- 예:
-
updatedAt(String, ISO 8601): 모임 수정 일시- 예:
"2025-12-11T10:24:48.20504"
- 예:
-
userStatus(Object): 현재 요청을 보낸 유저 기준의 모임 참여 상태-
isJoined(Boolean): 참여 여부-
true면 현재 이 모임에 참여 중
-
-
joinedAt(String or null, ISO 8601): 이 유저가 이 모임에 참여한 시각- 참여하지 않은 경우
null
- 참여하지 않은 경우
-
-
joinedMembers(JoinedMemberResponse[]): 모임에 참여 중인 모든 사용자 목록- 각 아이템:
-
userId(Number): 참여자 유저 ID -
groupRole(String): 모임 내 역할- 예:
"HOST","MEMBER"
- 예:
-
nickName(String): 참여자 닉네임 -
profileImage(String or null): 참여자 프로필 이미지 URL -
joinedAt(String, ISO 8601): 이 유저가 이 모임에 참여한 시각
-
- 각 아이템:
-
로그인 여부에 따라 응답 내용이 달라짐
- 비로그인: 모임 정보 + 참여자 목록만 조회
- 로그인: 위 정보 + 내 참여 상태(
userStatus)까지 포함
-
참여/취소 API와 동일한 응답 구조 사용
-
/attend,/cancel이후에도 항상 이GetGroupResponse구조로 내려가기 때문에 프론트에서는 “상세 화면 상태”를 한 타입으로 관리할 수 있습니다.
-
-
참여자 목록과 역할 정보를 함께 제공
-
joinedMembers.groupRole을 통해 호스트/일반 멤버 구분이 가능해 호스트 배지 표시, 호스트만 가능한 버튼 제어 등에 활용할 수 있습니다.
-
-
대표 이미지/썸네일을 바로 사용 가능
- 하나의 이미지에 대해 440x240, 100x100 두 가지 URL이 함께 내려오기 때문에 상세 화면, 리스트, 작은 아바타 등에서 바로 재사용할 수 있습니다.
노출된 모임 목록을 커서 기반 무한 스크롤 방식으로 조회합니다.
keyword가 있으면 태그(tag), 제목(title), 장소(location)에 대해 OR 조건으로 검색합니다.
Query Parameters
-
keyword(String, optional): 검색 키워드- 모임의 제목, 태그, 위치 중 하나라도 포함하면 검색 대상이 됨
- 예:
"스터디","강남","자바"
-
cursor(Number, optional): 다음 페이지 조회를 위한 커서 값- 이전 응답의
data.nextCursor값을 그대로 사용 - 첫 페이지 조회 시에는 생략
- 이전 응답의
-
size(Number, required): 한 번에 조회할 최대 개수- 예:
5,10,20등
- 예:
Headers
- No Required Request Headers
Example Endpoint
- 첫 페이지 조회
GET https://{baseUrl}/api/v1/groups?size=5- 다음 페이지 조회
GET https://{baseUrl}/api/v1/groups?size=5&cursor=11- 검색 + 첫 페이지
GET https://{baseUrl}/api/v1/groups?keyword=스터디&size=20{
"status": 200,
"success": true,
"data": {
"items": [
{
"id": 15,
"title": "커서 테스트 모임 15 (member 5)",
"location": "서울 강남구",
"locationDetail": "강남역 15번 출구 근처 카페",
"startTime": "2026-12-25T19:00:00",
"endTime": "2026-12-25T21:00:00",
"images": [
"https://cdn.example.com/groups/dummy/member_5_group_3_img0_440x240.webp"
],
"tags": [
"스터디",
"더미15"
],
"description": "커서 기반 페이징 테스트용 더미 모임입니다. 번호: 15",
"participantCount": 1,
"maxParticipants": 10,
"createdBy": {
"userId": 6,
"nickName": "CursorMember5",
"profileImage": null
},
"createdAt": "2025-12-11T10:32:31.246254",
"updatedAt": "2025-12-11T10:32:31.246254"
}
// ...
],
"nextCursor": 11
}
}상위 공통 응답
-
status(Number): HTTP 상태 코드 숫자값 (예: 200, 201) -
success(Boolean): 요청 성공 여부 -
data(Object): 모임 목록 및 다음 페이지 정보
data (모임 목록 응답)
-
items(GroupListItemResponse[]): 모임 목록 데이터 배열- 각 아이템은 개별 모임 카드에 해당
-
nextCursor(Number or null): 다음 페이지 조회를 위한 커서 값- 다음 요청 시
cursor파라미터로 그대로 사용 - 더 이상 조회할 데이터가 없으면
null
- 다음 요청 시
data.items[] (GroupListItemResponse – 모임 목록 아이템)
-
id(Number): 모임 ID -
title(String): 모임 제목 -
location(String): 모임 기본 위치 정보- 예:
"서울 강남구"
- 예:
-
locationDetail(String): 모임 상세 위치 정보- 예:
"강남역 15번 출구 근처 카페" - 없을 수 있음
- 예:
-
startTime(String, ISO 8601): 모임 시작 일시- 예:
"2026-12-25T19:00:00"
- 예:
-
endTime(String, ISO 8601): 모임 종료 일시- 예:
"2026-12-25T21:00:00"
- 예:
-
images(String[]): 모임 이미지 URL 목록- 각 요소는 이미지 한 장의 URL
- 일반적으로 첫 번째 이미지가 대표 이미지로 사용됨
- 최대 3장까지 사용 가능
-
tags(String[]): 모임 태그 목록- 예:
["스터디", "더미15"]
- 예:
-
description(String): 모임 상세 설명- 목록 화면에서 간략 설명/요약 용도로 사용 가능
-
participantCount(Number): 현재 참여 인원 수 -
maxParticipants(Number): 최대 참여 인원 수 -
createdBy(Object): 모임 생성자 정보-
userId(Number): 생성자 유저 ID -
nickName(String): 생성자 닉네임 -
profileImage(String or null): 생성자 프로필 이미지 URL -
profileMessage: 생성자 프로필 메시지
-
-
createdAt(String, ISO 8601): 모임 생성 일시- 예:
"2025-12-11T10:32:31.246254"
- 예:
-
updatedAt(String, ISO 8601): 모임 수정 일시- 예:
"2025-12-11T10:32:31.246254"
- 예:
-
커서 기반 무한 스크롤
-
nextCursor를 활용해 다음 페이지를 조회하는 방식 - 마지막 아이템의 ID를 커서로 사용하는 형태이며,
프론트에서는
nextCursor가null일 때 “더 보기” 버튼을 숨기면 됨.
-
-
공개 목록, 인증 불필요
-
Authorization없이 누구나 호출 가능 - 메인 피드/탐색 화면 등에 바로 사용할 수 있음.
-
-
검색과 페이징을 동시에 지원
-
keyword+cursor+size를 조합해 “키워드 검색 결과에 대한 무한 스크롤” UI를 구현할 수 있음.
-
-
목록용 경량 응답 구조
- 상세 정보(
userStatus,joinedMembers등)는 포함하지 않고, 카드 리스트에 필요한 핵심 정보만 포함하는 구조라 목록 조회 시에 상대적으로 가볍게 사용할 수 있음.
- 상세 정보(
기존 모임의 내용(제목, 위치, 일정, 태그, 설명, 정원)을 수정합니다.
이미지 수정은 이 API가 아니라 **그룹 이미지 API(/api/v1/groups/images/...)**를 통해 따로 처리합니다.
로그인한 사용자 중에서 **해당 모임의 호스트(생성자)**만 수정할 수 있습니다.
Path Parameter
-
groupId(Number, required): 수정할 모임 ID
Headers
Authorization: Bearer {accessToken}Content-Type: application/json
Body (JSON)
{
"title": "강남 자바 스터디 - 수정된 제목",
"location": "서울 서초구",
"locationDetail": "교대역 1번 출구 근처 카페",
"startTime": "2025-12-11T19:30:00",
"endTime": "2025-12-11T21:30:00",
"tags": [
"자바",
"백엔드",
"스터디",
"수정태그"
],
"description": "모임 내용을 수정한 케이스입니다. 장소/시간/태그/설명/정원 모두 변경.",
"maxParticipants": 12
}요청 필드 설명 (UpdateGroupRequest)
-
title(String, required): 수정할 모임 제목 -
location(String, required): 수정할 모임 기본 위치 정보 -
locationDetail(String, optional): 수정할 상세 위치 정보 -
startTime(String, required, ISO 8601): 수정할 모임 시작 일시- 예:
"2025-12-11T19:30:00" - 현재 시각 이후여야 함
- 예:
-
endTime(String, optional, ISO 8601): 수정할 모임 종료 일시- 예:
"2025-12-11T21:30:00" - 현재 시각 이후여야 함
- 예:
-
tags(String[], optional): 수정할 태그 목록- 기존 태그를 전체 교체하는 개념
-
description(String, required): 수정할 모임 설명 -
maxParticipants(Number, required): 수정할 최대 참여 인원- 최소 2명, 최대 12명
⚠️ 이 API에서는 이미지 수정은 하지 않습니다. 이미지는/api/v1/groups/images/...API에서 관리하고, 여기서는 텍스트/숫자 필드(내용, 위치, 시간, 정원, 태그)만 수정합니다.
Example Endpoint
PATCH https://{baseUrl}/api/v1/groups/1
Content-Type: application/json
Authorization: Bearer {accessToken}{
"status": 200,
"success": true,
"data": {
"id": 1,
"title": "강남 자바 스터디 - 수정된 제목",
"location": "서울 서초구",
"locationDetail": "교대역 1번 출구 근처 카페",
"startTime": "2025-12-11T19:30:00",
"endTime": "2025-12-11T21:30:00",
"images": [
{
"sortOrder": 0,
"imageId440x240": 1,
"imageId100x100": 2,
"imageUrl440x240": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211103742_0_d6b89514-c280-46d5-aac9-cb43a64538a5_440x240.webp",
"imageUrl100x100": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211103742_0_d6b89514-c280-46d5-aac9-cb43a64538a5_100x100.webp"
},
{
"sortOrder": 1,
"imageId440x240": 3,
"imageId100x100": 4,
"imageUrl440x240": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211103743_1_eb6f80ac-51b6-44d2-a825-19c107bffc16_440x240.webp",
"imageUrl100x100": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211103743_1_eb6f80ac-51b6-44d2-a825-19c107bffc16_100x100.webp"
}
],
"tags": [
"자바",
"백엔드",
"스터디",
"수정태그"
],
"description": "모임 내용을 수정한 케이스입니다. 장소/시간/태그/설명/정원 모두 변경.",
"participantCount": 1,
"maxParticipants": 12,
"createdBy": {
"userId": 1,
"nickName": "Beemo",
"profileImage": null
},
"createdAt": "2025-12-11T10:37:44.609491",
"updatedAt": "2025-12-11T10:37:47.2006077",
"userStatus": {
"isJoined": true,
"joinedAt": "2025-12-11T10:37:44.618516"
},
"joinedMembers": [
{
"userId": 1,
"groupRole": "HOST",
"nickName": "Beemo",
"profileImage": null,
"joinedAt": "2025-12-11T10:37:44.618516"
}
]
}
}상위 공통 응답
-
status(Number): HTTP 상태 코드 숫자값 (예: 200, 201) -
success(Boolean): 요청 성공 여부 -
data(Object): 모임 상세 정보
data (모임 정보)
-
id(Number): 모임 ID -
title(String): 모임 제목 -
location(String): 모임 기본 위치 정보 -
locationDetail(String): 모임 상세 위치 정보- 없을 수 있음
-
startTime(String, ISO 8601): 모임 시작 일시- 예:
"2025-12-11T19:30:00"
- 예:
-
endTime(String, ISO 8601): 모임 종료 일시- 예:
"2025-12-11T21:30:00"
- 예:
-
images(GroupImageItemResponse[]): 모임에 연결된 이미지 목록- 각 아이템:
-
sortOrder(Number): 이미지 노출 순서 (0부터 시작, 0이 대표 이미지) -
imageId440x240(Number): 440x240 사이즈 이미지 리소스 ID -
imageId100x100(Number): 100x100 사이즈 이미지 리소스 ID -
imageUrl440x240(String): 440x240 크기 이미지 URL -
imageUrl100x100(String): 100x100 크기 이미지 URL
-
- 각 아이템:
-
tags(String[]): 모임 태그 목록 (예:["자바", "백엔드", "스터디", "수정태그"]) -
description(String): 모임 상세 설명 -
participantCount(Number): 현재 참여 인원 수 -
maxParticipants(Number): 최대 참여 인원 수 -
createdBy(Object): 모임 생성자 정보-
userId(Number): 생성자 유저 ID -
nickName(String): 생성자 닉네임 -
profileImage(String or null): 생성자 프로필 이미지 URL -
profileMessage: 생성자 프로필 메시지
-
-
createdAt(String, ISO 8601): 모임 생성 일시- 예:
"2025-12-11T10:37:44.609491"
- 예:
-
updatedAt(String, ISO 8601): 모임 수정 일시- 예:
"2025-12-11T10:37:47.2006077"
- 예:
-
userStatus(Object): 현재 로그인한 유저 기준의 모임 참여 상태-
isJoined(Boolean): 참여 여부-
true면 현재 이 모임에 참여 중
-
-
joinedAt(String or null, ISO 8601): 이 유저가 이 모임에 참여한 시각- 참여하지 않은 경우
null
- 참여하지 않은 경우
-
-
joinedMembers(JoinedMemberResponse[]): 모임에 참여 중인 모든 사용자 목록- 각 아이템:
-
userId(Number): 참여자 유저 ID -
groupRole(String): 모임 내 역할- 예:
"HOST","MEMBER"
- 예:
-
nickName(String): 참여자 닉네임 -
profileImage(String or null): 참여자 프로필 이미지 URL -
joinedAt(String, ISO 8601): 이 유저가 이 모임에 참여한 시각
-
- 각 아이템:
-
호스트 전용 수정 API
-
Authorization이 필요하며, - 내부적으로는 해당 모임의 호스트(생성자)인 경우에만 수정 허용됩니다.
-
-
PATCH지만, 실제로는 “전체 내용 수정” 방식에 가깝게 동작
- 요청 DTO 상 모든 필드가 필수이기 때문에 “보낸 필드만 부분 수정”이 아니라, 모임 내용을 통으로 수정하는 방식에 가깝습니다.
-
이미지는 별도 API에서 관리
- 이 API는 텍스트/숫자 정보(제목, 위치, 설명, 태그, 정원, 시간)만 수정하고,
-
images는 현재 설정된 값이 그대로 유지됩니다. - 이미지를 변경하려면
/api/v1/groups/images/...엔드포인트를 사용해야 합니다.
-
응답 구조는 모임 상세 조회와 동일
- 수정 후 곧바로 최신 상태의 모임 상세 정보를 반환하므로,
- 프론트에서는 응답 데이터를 그대로 상세 화면 상태에 반영하면 됩니다.
이미 업로드된 이미지 URL들을 이용해서 **모임에 연결된 이미지 목록을 수정(교체)**합니다.
실제 파일 업로드는 /api/v1/groups/images/upload에서 먼저 수행하고,
이 API에서는 그때 받은 URL들을 이용해 정렬 순서와 함께 최종 확정하는 단계입니다.
Path Parameter
-
groupId(Number, required): 이미지를 수정할 모임 ID
Headers
Authorization: Bearer {accessToken}Content-Type: application/json
Body (JSON)
요청은 배열(Array) 형태이며, 각 요소는 하나의 이미지 정보를 나타냅니다.
[
{
"sortOrder": 0,
"imageUrl440x240": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211104047_0_656e4c0e-68ce-4676-a165-261d1c403dec_440x240.webp",
"imageUrl100x100": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211104047_0_656e4c0e-68ce-4676-a165-261d1c403dec_100x100.webp"
},
{
"sortOrder": 1,
"imageUrl440x240": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211104047_1_4c1153fb-4a95-4335-b06b-84d21d583ccc_440x240.webp",
"imageUrl100x100": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211104047_1_4c1153fb-4a95-4335-b06b-84d21d583ccc_100x100.webp"
},
{
"sortOrder": 2,
"imageUrl440x240": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211104047_2_e437745e-3277-47ae-80d3-7e2a709cba95_440x240.webp",
"imageUrl100x100": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211104047_2_e437745e-3277-47ae-80d3-7e2a709cba95_100x100.webp"
}
]배열의 각 요소:
-
sortOrder(Number): 이미지 노출 순서- 0부터 시작, 0이 대표 이미지
-
imageUrl440x240(String): 440x240 사이즈 이미지 URL- 보통 업로드 API 응답의
imageUrl440x240그대로 사용
- 보통 업로드 API 응답의
-
imageUrl100x100(String): 100x100 사이즈 썸네일 URL- 업로드 API 응답의
imageUrl100x100그대로 사용
- 업로드 API 응답의
/api/v1/groups/images/upload로 파일 업로드 → URL 리스트 확보- 이 URL들을 정렬 순서와 함께 배열로 보내
/images/{groupId}에 PATCH 하는 2단계 구조입니다.
Example Endpoint
PATCH https://{baseUrl}/api/v1/groups/images/1
Content-Type: application/json
Authorization: Bearer {accessToken}{
"status": 200,
"success": true,
"data": [
{
"sortOrder": 0,
"imageId440x240": 7,
"imageId100x100": 8,
"imageUrl440x240": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211104047_0_656e4c0e-68ce-4676-a165-261d1c403dec_440x240.webp",
"imageUrl100x100": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211104047_0_656e4c0e-68ce-4676-a165-261d1c403dec_100x100.webp"
},
{
"sortOrder": 1,
"imageId440x240": 9,
"imageId100x100": 10,
"imageUrl440x240": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211104047_1_4c1153fb-4a95-4335-b06b-84d21d583ccc_440x240.webp",
"imageUrl100x100": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211104047_1_4c1153fb-4a95-4335-b06b-84d21d583ccc_100x100.webp"
},
{
"sortOrder": 2,
"imageId440x240": 11,
"imageId100x100": 12,
"imageUrl440x240": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211104047_2_e437745e-3277-47ae-80d3-7e2a709cba95_440x240.webp",
"imageUrl100x100": "https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211104047_2_e437745e-3277-47ae-80d3-7e2a709cba95_100x100.webp"
}
]
}상위 공통 응답
-
status(Number): HTTP 상태 코드 숫자값 (예: 200, 201) -
success(Boolean): 요청 성공 여부 -
data(GroupImageItemResponse[]): 수정된 모임 이미지 목록
data[] (GroupImageItemResponse – 개별 이미지 정보)
-
sortOrder(Number): 이미지 노출 순서- 0부터 시작, 0이 대표 이미지
-
imageId440x240(Number): 440x240 사이즈 이미지 리소스 ID- 서버 내부에서 관리하는 이미지 식별자
-
imageId100x100(Number): 100x100 사이즈 이미지 리소스 ID -
imageUrl440x240(String): 440x240 크기 이미지 URL- 모임 카드/상세 화면에서 주로 사용하는 메인 썸네일
-
imageUrl100x100(String): 100x100 크기 이미지 URL- 작은 썸네일/리스트/아바타 형태 등에 사용 가능
-
호스트 전용 이미지 수정 API
-
Authorization이 필요하며, - 모임의 호스트(생성자)만 이미지를 수정할 수 있습니다.
-
-
“현재 이미지 목록 전체 교체” 방식
- 요청 바디에 전달한 배열이 해당 모임의 이미지 전체 목록이 됩니다.
- 이전에 연결돼 있던 이미지는 교체되며,
정렬 순서(
sortOrder)도 이 요청 내용을 기준으로 다시 설정됩니다.
-
파일 업로드와 URL 확정이 분리된 2단계 구조
-
/images/upload에서 실제 파일 업로드 → URL 리스트 받기 -
/images/{groupId}에서 이 URL들을 기반으로 모임 이미지 구성 - 프론트에서는 업로드 단계와 수정 단계를 명확히 분리해서 “업로드 미리보기 → 수정 확정” UI를 만들기 좋습니다.
-
-
응답을 그대로 상세 조회에 재사용 가능
- 응답 타입은
GroupImageItemResponse[]로, - 모임 상세 조회(
GetGroupResponse.images)에서도 동일한 구조를 사용하므로 수정 직후 응답을 그대로 상세 화면 이미지 목록에 반영할 수 있습니다.
- 응답 타입은
특정 모임을 삭제합니다. **모임 호스트(생성자)**만 삭제할 수 있으며, 삭제된 모임은 이후 조회 API에서 더 이상 노출되지 않습니다.
Path Parameter
-
groupId(Number, required): 삭제할 모임 ID
Headers
Authorization: Bearer {accessToken}
Body
- No Required Request Body
Example Endpoint
DELETE https://{baseUrl}/api/v1/groups/1
Authorization: Bearer {accessToken}HTTP/1.1 204 No Content
Content-Type: application/json이 API는 HTTP 204 No Content를 반환하며, 응답 본문이 존재하지 않으므로 별도의 응답 필드는 없습니다.
- 상태 코드만으로 삭제 성공 여부를 판단합니다.
-
204→ 삭제 성공 - 그 외 에러 코드 → 권한 없음, 존재하지 않는 모임 등 에러 케이스
-
-
호스트 전용 삭제 기능
- 모임의 생성자(호스트)만 삭제할 수 있도록 서버에서 권한을 검증합니다.
- 일반 참여자나 비로그인 유저는 삭제 요청 시 에러 응답을 받게 됩니다.
-
No Content 패턴 사용
- 삭제 성공 시 별도의 메시지나 데이터 없이
204 No Content만 반환합니다. - 프론트에서는 응답 바디 파싱 없이 상태 코드만 보고 처리하면 됩니다.
- 예: 삭제 성공 후 목록 페이지로 리다이렉트, 토스트 알림 띄우기 등
- 삭제 성공 시 별도의 메시지나 데이터 없이
-
후속 조회에서 완전히 사라짐
- 삭제된 모임은
- 모임 상세 조회 (
GET /api/v1/groups/{groupId}) - 모임 목록 조회 (
GET /api/v1/groups) - 내 모임 목록 (
GET /api/v1/groups/me) 에서 더 이상 보이지 않도록 처리됩니다.
- 모임 상세 조회 (
- 삭제된 모임은
특정 모임에 연결된 이미지들을 전부 삭제합니다. 이미지 정보만 제거되며, 모임 자체는 그대로 유지됩니다.
이미지 삭제는 **모임 호스트(생성자)**만 할 수 있습니다.
Path Parameter
-
groupId(Number, required): 이미지를 삭제할 모임 ID
Headers
Authorization: Bearer {accessToken}
Body
- No Required Request Body
Example Endpoint
DELETE https://{baseUrl}/api/v1/groups/images/1
Authorization: Bearer {accessToken}HTTP/1.1 204 No Content
Content-Type: application/json이 API는 HTTP 204 No Content만 반환하며, 응답 바디가 없기 때문에 별도의 응답 필드는 존재하지 않습니다.
-
204→ 이미지 삭제 성공 - 그 외 상태 코드 → 권한 없음, 존재하지 않는 모임/이미지, 기타 에러
-
이미지 전용 삭제 API
- 모임 자체는 삭제하지 않고, 연결된 모든 이미지 정보만 제거합니다.
- 이후 모임 상세 조회 시
images배열이 빈 배열 또는 이미지 없음 상태로 내려오게 됩니다.
-
호스트 권한 필요
-
Authorization헤더의 유저가 해당 모임의 호스트일 때만 삭제가 허용됩니다.
-
-
응답이 완전히 비어 있음
- 컨트롤러에서
ResponseEntity.noContent().build()를 사용하기 때문에 프론트에서는 응답 바디를 파싱하지 말고 상태 코드만 확인하면 됩니다. - 삭제 후에는 보통:
- 이미지 업로드/수정 모달 초기화
- “이미지가 삭제되었습니다” 토스트 노출
- 상세 화면에서 이미지 영역을 플레이스홀더로 교체 같은 후속 UI 처리를 하면 됩니다.
- 컨트롤러에서
현재 로그인한 유저를 기준으로 다음 세 가지 유형의 모임 목록을 조회합니다.
-
current: 지금 참여 중이거나 진행 예정인 모임 -
myPost: 내가 생성한 모임 -
past: 과거에 참여했던 모임
커서 기반 페이징(cursor)으로 무한 스크롤 형태 조회를 지원합니다.
Query Parameters
-
type(String, required): 조회할 모임 목록 타입-
"current": 현재 참여 중인 모임 -
"myPost": 내가 만든(호스트인) 모임 -
"past": 과거에 참여했던 모임
-
-
cursor(Number, optional): 다음 페이지 조회를 위한 기준 커서- 첫 페이지 조회 시 생략
- 이전 응답의
data.nextCursor값을 그대로 사용
-
size(Number, required): 한 번에 조회할 최대 개수- 예:
5,10,20등
- 예:
Headers
Authorization: Bearer {accessToken}
Body
- No Required Request Body
Example Endpoint
GET https://{baseUrl}/api/v1/groups/me?type=current&size=5
Authorization: Bearer {accessToken}페이징 2페이지 예시:
GET https://{baseUrl}/api/v1/groups/me?type=current&size=5&cursor=6
Authorization: Bearer {accessToken}{
"status": 200,
"success": true,
"data": {
"items": [
{
"id": 17,
"title": "강남 자바 스터디 - PAST",
"location": "서울 강남구",
"locationDetail": "강남역 2번 출구 근처 카페",
"startTime": "2026-01-10T19:00:00",
"endTime": "2026-01-10T21:00:00",
"images": [
"https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251211105021_0_52eb2793-2e4a-40a5-b6d1-ff496064d859_440x240.webp"
],
"tags": [
"자바",
"과거모임"
],
"description": "내 모임 목록(past) 테스트용 모임입니다.",
"participantCount": 1,
"maxParticipants": 12,
"createdBy": {
"userId": 1,
"nickName": "Beemo",
"profileImage": null
},
"createdAt": "2025-12-11T10:50:25.11603",
"updatedAt": "2025-12-11T10:50:25.11603"
}
// ... 생략 (current 모임들)
],
"nextCursor": 6
}
}상위 공통 응답
-
status(Number): HTTP 상태 코드 숫자값 (예: 200, 201) -
success(Boolean): 요청 성공 여부 -
data(Object): 내 모임 목록 및 페이징 정보
data (내 모임 목록 + 커서 정보)
-
items(GroupListItemResponse[]): 현재 페이지의 모임 리스트 -
nextCursor(Number or null): 다음 페이지 조회를 위한 커서 값- 다음 페이지가 있으면 마지막 아이템 기준 커서 값 (예:
6) - 더 이상 조회할 데이터가 없으면
null
- 다음 페이지가 있으면 마지막 아이템 기준 커서 값 (예:
data.items[] (GroupListItemResponse – 각 모임 요약 정보)
각 요소는 한 개의 모임을 나타냅니다.
-
id(Number): 모임 ID -
title(String): 모임 제목 -
location(String): 모임 기본 위치 정보- 예:
"서울 강남구"
- 예:
-
locationDetail(String): 모임 상세 위치 정보- 예:
"강남역 CURRENT 카페 5번 출구 근처"
- 예:
-
startTime(String, ISO 8601): 모임 시작 일시- 예:
"2025-12-16T10:50:07.038234"
- 예:
-
endTime(String, ISO 8601): 모임 종료 일시- 예:
"2025-12-16T12:50:07.038234"
- 예:
-
images(String[]): 모임 대표 이미지 URL 목록- 0개일 수도 있습니다. (이미지 없는 모임)
- 예:
[]["https://..._440x240.webp"]
-
tags(String[]): 모임 태그 목록- 예:
["더미", "current", "seq-5"]
- 예:
-
description(String): 모임 설명- 예:
"내 모임(current) 더미 데이터, seq=5"
- 예:
-
participantCount(Number): 현재 이 모임에 참여 중인 인원 수- Host + Member 수를 포함한 실제 참여자 수
-
maxParticipants(Number): 모임 최대 정원 -
createdBy(Object): 모임 생성자(호스트) 정보-
userId(Number): 생성자 유저 ID -
nickName(String): 생성자 닉네임 -
profileImage(String or null): 생성자 프로필 이미지 URL -
profileMessage: 생성자 프로필 메시지
-
-
createdAt(String, ISO 8601): 모임이 생성된 시각- 예:
"2025-12-11T10:50:07.222316"
- 예:
-
updatedAt(String, ISO 8601): 모임 정보가 마지막으로 수정된 시각- 예:
"2025-12-11T10:50:07.222316"
- 예:
-
반드시 로그인 필요
-
@AuthenticationPrincipal을 사용하므로,Authorization: Bearer {accessToken}헤더가 없으면 호출할 수 없습니다. - 항상 “현재 로그인한 유저 기준”으로만 데이터가 조회됩니다.
-
-
타입(type)에 따라 의미가 달라짐
-
current: 지금 참여 중이거나 다가오는 모임들만 포함 -
myPost: 내가 호스트인 모임들만 포함 -
past: 이미 종료된 모임들만 포함 - 서버에서 time 기준 + GroupUser/Host 여부를 조합해 필터링합니다.
-
-
공개 모임 목록과는 별도의 전용 뷰
-
/api/v1/groups는 “전체 공개 노출용” 목록이고, -
/api/v1/groups/me는 “나와 관련된 모임만 필터링된 개인화 리스트”입니다. - 같은 GroupListItemResponse 구조를 재사용하기 때문에, 프론트에서는 공개 목록/내 목록을 같은 카드 컴포넌트로 렌더링할 수 있습니다.
-
-
이미지 배열이 비어 있을 수 있음
- 현재 예시처럼 더미 데이터에는 이미지가 없는 모임도 있으므로,
프론트에서는
images.length === 0일 때 기본 이미지/플레이스홀더를 보여주는 처리가 필요합니다.
- 현재 예시처럼 더미 데이터에는 이미지가 없는 모임도 있으므로,
프론트에서는
-
커서 기반 무한 스크롤
-
nextCursor를 기준으로 다음 페이지를 요청하는 구조입니다. - 예:
- 첫 요청:
/me?type=current&size=5 - 응답의
nextCursor = 6 - 다음 요청:
/me?type=current&size=5&cursor=6
- 첫 요청:
- 더 이상 데이터가 없으면
nextCursor가null이 되므로 스크롤 이벤트를 막거나 “마지막 페이지입니다” 안내를 할 수 있습니다.
-
DELETE /api/v1/groups/{groupId}/images/one
특정 모임에 연결된 이미지(URL) 1건을 삭제합니다. 삭제는 호스트(생성자)만 수행할 수 있으며, 요청한 url이 해당 모임의 이미지로 등록되어 있어야 합니다.
이 API는 “단 건 삭제”만 담당합니다. 440x240 / 100x100처럼 한 장의 원본에서 파생된 2개 이미지(메인/썸네일)를 모두 삭제하려면, 모임 서비스(또는 프론트)가 URL을 각각 2번 호출하여 삭제해야 합니다.
Path Parameter
-
groupId(Number, required): 삭제 대상 모임 ID
Query Parameter
-
url(String, required): 삭제할 이미지 URL 예:https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/..._440x240.webp해당 API는 URL 기반으로 삭제합니다. DB에 저장된 이미지 식별 기준이 URL이기 때문입니다.
Headers
-
Authorization: Bearer {accessToken}(required)
Example Endpoint
1) 메인 이미지(440x240) 단 건 삭제
DELETE https://{baseUrl}/api/v1/groups/1/images/one
?url=https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251216003552_0_581c7311-d59a-420b-8280-87106ad019bd_440x240.webp
Authorization: Bearer {accessToken}2) 썸네일(100x100) 단 건 삭제
DELETE https://{baseUrl}/api/v1/groups/1/images/one
?url=https://we-go-bucket.s3.ap-northeast-2.amazonaws.com/20251216003552_0_581c7311-d59a-420b-8280-87106ad019bd_100x100.webp
Authorization: Bearer {accessToken}204 No Content
삭제 성공 시 응답 본문 없이 204만 반환합니다.
HTTP/1.1 204 No Content- 호스트 전용 API 해당 모임의 생성자(HOST)만 이미지 삭제가 가능합니다
- URL 기반 단건 삭제 이미지 리소스는 모임 DB에 URL로 연결되어 있어, 삭제도 URL을 기준으로 수행합니다
- 파생 이미지(440/100) 삭제는 2번 호출 모임 대표 이미지 1장의 파생 리소스(예: 440x240, 100x100)를 모두 지우려면 각 URL을 대상으로 2번 요청해야 합니다
- No Content 패턴(204) 성공 시 응답 바디가 없으므로 프론트는 상태 코드만 확인하면 됩니다.