Socket.io를 사용한 실시간 채팅 시스템과 REST API를 제공합니다.
Base URL: http://localhost:3001
인증: JWT 인증 필요 (모든 API)
응답 형식: JSON (공통 응답 포맷)
GET /chats
내가 포함된 채팅방 목록을 반환합니다.
파라미터
타입
설명
-
-
경로 파라미터 없음
파라미터
타입
필수
설명
cursor
number
옵션
페이징을 위한 커서 (마지막으로 본 채팅방 ID)
limit
number
옵션
한 번에 가져올 채팅방 수 (기본값: 15, 최대값: 50)
없음
필드
타입
설명
[].id
number
채팅방 고유 ID
[].name
string?
채팅방 이름 (그룹 채팅방만, null: 1:1 채팅방)
[].type
string
채팅방 타입 ("private" 또는 "group")
[].avatar_url
string?
채팅방 아바타 이미지 URL (base URL 포함, 없으면 null)
[].created_at
string
채팅방 생성 시간 (ISO 8601)
[].memberCount
number
채팅방 총 멤버 수
[].unread_count
number
읽지 않은 메시지 개수 (자신이 보낸 메시지는 제외)
[].lastMessage
object?
마지막 메시지 정보 (없으면 null)
[].lastMessage.id
number
마지막 메시지 ID
[].lastMessage.content
string
메시지 내용
[].lastMessage.type
string
메시지 타입 ("text", "image", "video")
[].lastMessage.sender_id
number
발신자 ID
[].lastMessage.created_at
string
메시지 발신 시간 (ISO 8601)
[].other_users[]
array
나를 제외한 멤버들 (그룹 채팅방)
[].other_users[].id
number
멤버 ID
[].other_users[].nickname
string
멤버 닉네임
[].other_users[].avatar_url
string?
멤버 프로필 이미지 URL
[].other_user
object?
상대방 정보 (1:1 채팅방)
[].other_user.id
number
상대방 ID
[].other_user.nickname
string
상대방 닉네임
[].other_user.avatar_url
string?
상대방 프로필 이미지 URL
{
"code" : 200 ,
"message" : " 채팅방 목록 조회 성공" ,
"data" : {
"chat_rooms" : [
{
"id" : 1 ,
"name" : " 개발팀" ,
"type" : " group" ,
"avatar_url" : " http://localhost:3001/uploads/2024/01/15/avatar.jpg" ,
"created_at" : " 2024-01-01T00:00:00.000Z" ,
"memberCount" : 3 ,
"unread_count" : 5 ,
"lastMessage" : {
"id" : 100 ,
"content" : " 안녕하세요!" ,
"type" : " text" ,
"sender_id" : 2 ,
"created_at" : " 2023-12-15T10:30:00.000Z"
}
"other_users" : [
{
"id" : 2 ,
"nickname" : " 김철수" ,
"avatar_url" : " http://localhost:3001/uploads-profile/2024/01/15/user2.jpg"
}
]
}
],
"hasNext" : true ,
"nextCursor" : 1
}
}
코드
설명
200
성공
401
인증 실패
500
서버 오류
삭제되고 메모리에서 해제된 채팅방은 제외됩니다.
사용자가 나간 채팅방 (status: 'left')은 목록에서 제외됩니다.
채팅방은 마지막 메시지 시간 기준으로 역순 정렬됩니다 (최신 대화 순).
마지막 메시지가 없는 새 채팅방은 생성 시간으로 자연스럽게 포함됩니다.
1:1 채팅방의 name은 항상 null입니다.
avatar_url은 설정되지 않은 경우 null입니다.
페이징을 지원하며 첫 페이지는 chat 만 호출하고 다음 페이지는 ?cursor={nextCursor}를 사용하여 조회합니다.
hasNext: false이면 더 이상 페이지가 없음을 의미합니다.
PATCH /chats/{chatRoomId}/read
사용자가 채팅방의 모든 메시지를 읽음 처리합니다.
파라미터
타입
설명
chatRoomId
number
채팅방 ID
파라미터
타입
필수
설명
-
-
-
쿼리 파라미터 없음
없음
필드
타입
설명
success
boolean
작업 성공 여부 (항상 true)
{
"code" : 200 ,
"message" : " 채팅방 읽음 처리 성공" ,
"data" : {
"success" : true
}
}
코드
설명
200
성공
400
잘못된 채팅방 ID
401
인증 실패
403
채팅방 멤버가 아님
404
채팅방 없음
500
서버 오류
채팅방의 가장 최근 메시지 ID를 last_read_message_id로 업데이트합니다.
채팅방 목록 조회 시 읽지 않은 메시지 개수가 0으로 표시됩니다.
GET /chats/unread-count
사용자가 읽지 않은 메시지의 총 개수를 반환합니다. 헤더의 알림 표시 등에 사용됩니다.
파라미터
타입
설명
-
-
경로 파라미터 없음
파라미터
타입
필수
설명
-
-
-
쿼리 파라미터 없음
없음
필드
타입
설명
unread_count
number
읽지 않은 메시지의 총 개수 (자신이 보낸 메시지 제외)
{
"code" : 200 ,
"message" : " 읽지 않은 메시지 총 개수 조회 성공" ,
"data" : {
"unread_count" : 3
}
}
코드
설명
200
성공
401
인증 실패
500
서버 오류
401 인증 실패
{
"code" : 401 ,
"message" : " 인증이 필요합니다."
}
500 서버 오류
{
"code" : 500 ,
"message" : " 읽지 않은 메시지 총 개수 조회에 실패했습니다."
}
사용자가 속한 채팅방의 모든 읽지 않은 메시지 개수를 합산하여 총 개수를 반환합니다.
각 채팅방별 last_read_message_id보다 큰 ID를 가진 메시지를 카운트합니다.
자신이 보낸 메시지는 제외하고 계산합니다.
POST /chats/private
두 명의 사용자 간 개인 채팅방을 생성합니다.
파라미터
타입
설명
-
-
경로 파라미터 없음
파라미터
타입
필수
설명
-
-
-
쿼리 파라미터 없음
필드
타입
필수
설명
userId
number
필수
상대방 사용자 ID
필드
타입
설명
chatRoomId
number
채팅방 ID
isNewlyCreated
boolean
새로 생성된 채팅방인지 여부 (true: 새로 생성됨, false: 기존 채팅방 재활용)
{
"code" : 201 ,
"message" : " 1:1 채팅방 생성 성공" ,
"data" : {
"chatRoomId" : 1 ,
"isNewlyCreated" : true
}
}
{
"code" : 200 ,
"message" : " 기존 채팅방을 활용합니다" ,
"data" : {
"chatRoomId" : 5 ,
"isNewlyCreated" : false
}
}
{
"code" : 400 ,
"message" : " 잘못된 요청입니다." ,
"errors" : [
{
"field" : " userId" ,
"message" : " 올바른 사용자 ID를 입력해주세요."
}
]
}
코드
설명
201
생성 성공
400
유효성 검사 실패
401
인증 실패
500
서버 오류
이미 존재하는 1:1 채팅방의 경우 기존 방의 ID를 반환합니다.
생성된 채팅방은 자동으로 private 타입으로 설정됩니다.
요청자와 대상 사용자가 자동으로 멤버로 추가됩니다.
POST /chats/image-upload
채팅 메시지로 보낼 이미지를 업로드합니다.
파라미터
타입
설명
-
-
경로 파라미터 없음
파라미터
타입
필수
설명
-
-
-
쿼리 파라미터 없음
Request Body (multipart/form-data)
필드
타입
필수
설명
image
file
필수
업로드할 이미지 파일 (JPG, PNG, GIF, WebP 등)
필드
타입
설명
image_path
string
업로드된 이미지의 경로 (DB 저장용)
url
string
완전한 이미지 접근 URL
filename
string
생성된 고유 파일명
size
number
파일 크기 (bytes)
{
"code" : 200 ,
"message" : " 이미지가 업로드되었습니다." ,
"data" : {
"image_path" : " /uploads-chat/2024/10/10/image123_1703123456789_abc123.jpg" ,
"url" : " http://localhost:3001/uploads-chat/2024/10/10/image123_1703123456789_abc123.jpg" ,
"filename" : " image123_1703123456789_abc123.jpg" ,
"size" : 245760
}
}
코드
설명
200
업로드 성공
400
잘못된 파일 형식 또는 파일 없음
401
인증 실패
413
파일 크기 초과 (10MB)
500
서버 오류
지원되는 파일 형식: JPG, JPEG, PNG, GIF, WebP, HEIC, HEIF
최대 파일 크기: 10MB
파일은 uploads-chat/image/년/월/일/ 폴더에 저장됩니다.
스토리지 분기 : STORAGE_DRIVER 환경변수에 따라 저장소가 결정됩니다
'local': 프로젝트 루트의 로컬 파일시스템에 저장
'naver-cloud': 네이버 클라우드 Object Storage에 저장
image_path는 DB에 저장할 경로로, 클라이언트에서 baseUrl + image_path로 완전한 URL을 구성합니다.
두 스토리지 타입 모두 동일한 URL 포맷을 유지하여 API 응답의 일관성을 보장합니다.
업로드된 이미지는 소켓을 통해 type: 'image', content: image_path로 채팅 메시지로 전송될 수 있습니다.
POST /chats/video-upload
채팅 메시지로 보낼 비디오를 업로드합니다. 선택적으로 편집(trim/crop)할 수 있습니다.
파라미터
타입
설명
-
-
경로 파라미터 없음
파라미터
타입
필수
설명
-
-
-
쿼리 파라미터 없음
Request Body (multipart/form-data)
필드
타입
필수
설명
video
file
필수
업로드할 비디오 파일 (MP4, MOV, AVI, WebM 등)
trimStart
number
선택
자르기 시작 시간 (밀리초)
trimEnd
number
선택
자르기 종료 시간 (밀리초)
cropArea
string
선택
크롭 영역 JSON (예: {"x":0.1,"y":0.1,"width":0.8,"height":0.8})
Request Body Fields (cropArea JSON)
필드
타입
필수
설명
x
number
필수
크롭 시작 X 좌표 (0-1, 비디오 너비의 비율)
y
number
필수
크롭 시작 Y 좌표 (0-1, 비디오 높이의 비율)
width
number
필수
크롭 너비 (0-1, 비디오 너비의 비율)
height
number
필수
크롭 높이 (0-1, 비디오 높이의 비율)
필드
타입
설명
video_path
string
업로드된 비디오의 경로 (DB 저장용)
thumbnail_path
string
생성된 썸네일의 경로 (DB 저장용)
video_url
string
완전한 비디오 접근 URL
thumbnail_url
string
완전한 썸네일 접근 URL
size
number
비디오 파일 크기 (bytes)
{
"code" : 200 ,
"message" : " 비디오가 업로드되었습니다." ,
"data" : {
"video_path" : " /uploads-chat-video/2024/11/12/video_1703123456789_abc123.mp4" ,
"thumbnail_path" : " /uploads-chat-thumbnail/2024/11/12/thumb_1703123456789_abc123.jpg" ,
"video_url" : " http://localhost:3001/uploads-chat-video/2024/11/12/video_1703123456789_abc123.mp4" ,
"thumbnail_url" : " http://localhost:3001/uploads-chat-thumbnail/2024/11/12/thumb_1703123456789_abc123.jpg" ,
"size" : 5242880
}
}
{
"code" : 200 ,
"message" : " 비디오가 업로드되고 편집되었습니다." ,
"data" : {
"video_path" : " /uploads-chat-video/2024/11/12/edited_1703123456789_def456.mp4" ,
"thumbnail_path" : " /uploads-chat-thumbnail/2024/11/12/thumb_edited_1703123456789_def456.jpg" ,
"video_url" : " http://localhost:3001/uploads-chat-video/2024/11/12/edited_1703123456789_def456.mp4" ,
"thumbnail_url" : " http://localhost:3001/uploads-chat-thumbnail/2024/11/12/thumb_edited_1703123456789_def456.jpg" ,
"size" : 3145728
}
}
코드
설명
200
업로드 성공
400
잘못된 파일 형식, 파라미터 오류
401
인증 실패
413
파일 크기 초과 (75MB)
500
서버 오류
지원되는 파일 형식: MP4, MOV, AVI, WebM, MKV, FLV
최대 파일 크기: 75MB
비디오는 uploads-chat/video/년/월/일/ 폴더에 저장됩니다.
썸네일은 uploads-chat/video-thumbnail/년/월/일/ 폴더에 자동 생성됩니다.
스토리지 분기 : STORAGE_DRIVER 환경변수에 따라 저장소가 결정됩니다
'local': 프로젝트 루트의 로컬 파일시스템에 저장
'naver-cloud': 네이버 클라우드 Object Storage에 저장
두 스토리지 타입 모두 동일한 URL 포맷을 유지하여 API 응답의 일관성을 보장합니다.
편집 파라미터가 제공되면 FFmpeg를 사용해 비디오를 실시간 편집합니다.
video_path와 thumbnail_path는 DB에 저장할 경로입니다.
업로드된 비디오는 소켓을 통해 type: 'video', content: video_path로 채팅 메시지로 전송될 수 있습니다.
편집 시 스케일링(720p 제한), 크롭, 트림이 동시에 적용됩니다.
POST /chats/group
여러 명의 사용자가 참여할 수 있는 그룹 채팅방을 생성합니다.
파라미터
타입
설명
-
-
경로 파라미터 없음
파라미터
타입
필수
설명
-
-
-
쿼리 파라미터 없음
{
"name" : " 개발팀" ,
"memberIds" : [2 , 3 , 4 ]
}
필드
타입
필수
설명
name
string
필수
채팅방 이름 (1-100자)
memberIds
number[]
필수
초대할 멤버 ID 배열 (1-50명)
필드
타입
설명
chatRoomId
number
생성된 채팅방 ID
isNewlyCreated
boolean
새로 생성된 채팅방인지 여부 (true: 새로 생성됨, false: 기존 채팅방 재활용)
{
"code" : 201 ,
"message" : " 그룹 채팅방 생성 성공" ,
"data" : {
"chatRoomId" : 2
}
}
코드
설명
201
생성 성공
400
유효성 검사 실패
401
인증 실패
500
서버 오류
생성된 채팅방은 자동으로 group 타입으로 설정됩니다.
요청자는 자동으로 멤버에 포함됩니다.
중복된 멤버 ID는 허용되지 않습니다.
DELETE /chats/{chatRoomId}/members/me
현재 로그인한 사용자가 채팅방에서 나갑니다.
파라미터
타입
설명
chatRoomId
number
채팅방 ID
파라미터
타입
필수
설명
-
-
-
쿼리 파라미터 없음
없음
필드
타입
설명
success
boolean
작업 성공 여부 (항상 true)
{
"code" : 200 ,
"message" : " 채팅방 나가기 성공" ,
"data" : {
"success" : true
}
}
코드
설명
200
성공
400
잘못된 채팅방 ID
401
인증 실패
403
채팅방 멤버가 아님
404
채팅방 없음
500
서버 오류
1:1 채팅방에서 나가면 status가 'left'로 변경되어 목록에서 숨겨지지만 데이터는 유지됩니다 (재참여 가능).
그룹 채팅방에서 나가면 완전히 삭제됩니다.
그룹 채팅방에서 마지막 멤버가 나가면 채팅방이 자동 삭제됩니다.
그룹 채팅방에서 나갈 때 : 시스템 메시지(type: 'system')가 자동 생성되어 채팅방에 브로드캐스트됩니다.
메시지 내용: {나가는 사용자 닉네임}님이 채팅방에서 나가셨습니다.
마지막 멤버가 나가는 경우는 시스템 메시지가 생성되지 않습니다.
POST /chats/{chatRoomId}/invite
기존 채팅방에 새로운 사용자를 초대합니다. 초대 성공 시 시스템 메시지가 채팅방에 자동으로 생성됩니다.
파라미터
타입
설명
chatRoomId
number
채팅방 ID
파라미터
타입
필수
설명
-
-
-
쿼리 파라미터 없음
필드
타입
필수
설명
user_id
number
필수
초대할 사용자 ID
필드
타입
설명
success
boolean
작업 성공 여부 (항상 true)
{
"code" : 200 ,
"message" : " 김철수님이 채팅방에 초대되었습니다." ,
"data" : {
"success" : true
}
}
{
"code" : 400 ,
"message" : " 잘못된 요청입니다." ,
"errors" : [
{
"field" : " user_id" ,
"message" : " 올바른 사용자 ID를 입력해주세요."
}
]
}
코드
설명
200
초대 성공
400
유효성 검사 실패
401
인증 실패
403
권한 없음 (채팅방 멤버가 아님)
404
채팅방 없음
500
서버 오류
그룹 채팅방만 초대 가능 (1:1 채팅방은 별도 생성)
초대자는 채팅방 멤버여야 함
대상 사용자가 이미 멤버인 경우 초대 불가
초대 성공 시 시스템 메시지(type: 'system')가 자동 생성되어 브로드캐스트됨
클라이언트에서는 시스템 메시지를 특별한 UI로 표시
GET /chats/{chatRoomId}
채팅방 상세 정보를 조회합니다.
파라미터
타입
설명
chatRoomId
number
채팅방 ID
파라미터
타입
필수
설명
-
-
-
쿼리 파라미터 없음
없음
필드
타입
설명
id
number
채팅방 ID
name
string?
채팅방 이름
type
string
채팅방 타입
avatar_url
string?
채팅방 아바타 URL (base URL 포함)
created_at
string
생성 시간 (ISO 8601)
latest_notices[]
array
최근 공지사항 목록 (최대 3개)
latest_notices[].notice_id
number
공지사항 ID
latest_notices[].content
string
공지 내용
latest_notices[].user_nickname
string
작성자 닉네임
latest_notices[].created_at
string
공지 작성 시간 (ISO 8601)
chat_room_images_videos[]
array
채팅방 최근 이미지/비디오 목록 (최대 5개)
chat_room_images_videos[].message_id
number
메시지 ID
chat_room_images_videos[].type
string
메시지 타입 ("image" 또는 "video")
chat_room_images_videos[].content
string
메시지 내용 (이미지/비디오 URL 등)
chat_room_images_videos[].created_at
string
메시지 발신 시간 (ISO 8601)
members[]
array
채팅방 멤버 목록
members[].id
number
ChatMember 테이블 ID
members[].user_id
number
User 테이블 사용자 ID
members[].joined_at
string
참가 시간 (ISO 8601)
members[].user
object
사용자 정보
members[].user.id
number
사용자 ID
members[].user.nickname
string
사용자 닉네임
members[].user.profile_img
string?
프로필 이미지 URL
{
"code" : 200 ,
"message" : " 채팅방 상세 조회 성공" ,
"data" : {
"id" : 1 ,
"name" : " 개발팀" ,
"type" : " group" ,
"avatar_url" : " http://localhost:3001/uploads/avatar.jpg" ,
"created_at" : " 2024-01-01T00:00:00.000Z" ,
"latest_notices" : [
{
"notice_id" : 5 ,
"content" : " 채팅방 규칙을 꼭 확인해주세요." ,
"user_nickname" : " 관리자" ,
"created_at" : " 2024-09-18T02:00:00.000Z"
},
{
"notice_id" : 4 ,
"content" : " 내일 팀 미팅 있습니다." ,
"user_nickname" : " 팀장" ,
"created_at" : " 2024-09-17T10:30:00.000Z"
}
],
"chat_room_images_videos" : [
{
"message_id" : 100 ,
"type" : " image" ,
"content" : " http://localhost:3001/uploads-chat/2024/11/12/image123.jpg" ,
"created_at" : " 2024-09-18T01:00:00.000Z"
},
{
"message_id" : 98 ,
"type" : " video" ,
"content" : " {\" video_url\" :\" http://localhost:3001/uploads-chat-video/2024/11/12/video456.mp4\" ,\" thumbnail_url\" :\" http://localhost:3001/uploads-chat-thumbnail/2024/11/12/thumb456.jpg\" }" ,
"created_at" : " 2024-09-17T23:00:00.000Z"
}
],
"members" : [
{
"id" : 1 ,
"user_id" : 1 ,
"joined_at" : " 2024-01-01T00:00:00.000Z" ,
"user" : {
"id" : 1 ,
"nickname" : " 사용자1" ,
"profile_img" : " http://localhost:3001/uploads-profile/2024/01/15/user1.jpg"
}
}
]
}
}
코드
설명
200
성공
400
잘못된 채팅방 ID
401
인증 실패
403
채팅방 멤버가 아님
404
채팅방 없음
500
서버 오류
latest_notices는 최대 3개의 최근 공지사항을 최신순으로 표시합니다.
chat_room_images_videos는 채팅방 내 image/video 타입 메시지 중 가장 최근 5개를 표시합니다.
공지사항이나 미디어 파일이 없는 경우 빈 배열로 반환됩니다.
멤버 목록에는 나 자신도 포함됩니다.
GET /chats/{chatRoomId}/media
채팅방에서 최근 30일 이내의 미디어 메시지(이미지/비디오)를 최대 30개까지 조회합니다.
파라미터
타입
설명
chatRoomId
number
채팅방 ID
파라미터
타입
필수
설명
limit
number
선택
최대 조회 개수 (1-30, 기본값: 30)
없음
필드
타입
설명
media[]
array
미디어 메시지 목록
media[].message_id
number
메시지 ID
media[].type
string
미디어 타입 ("image" 또는 "video")
media[].content
string
미디어 파일 URL (base URL 포함)
media[].created_at
string
메시지 발신 시간 (ISO 8601)
media[].sender
object
발신자 정보
media[].sender.id
number
발신자 ID
media[].sender.nickname
string
발신자 닉네임
total_count
number
전체 미디어 메시지 개수 (페이징 등에 활용)
{
"code" : 200 ,
"message" : " 채팅방 미디어 조회 성공" ,
"data" : {
"media" : [
{
"message_id" : 150 ,
"type" : " image" ,
"content" : " http://localhost:3001/uploads-chat/2024/11/11/image123.jpg" ,
"created_at" : " 2024-11-11T14:30:00.000Z" ,
"sender" : {
"id" : 2 ,
"nickname" : " 김철수"
}
},
{
"message_id" : 145 ,
"type" : " video" ,
"content" : " {\" video_url\" :\" http://localhost:3001/uploads-chat-video/2024/11/10/video456.mp4\" ,\" thumbnail_url\" :\" http://localhost:3001/uploads-chat-thumbnail/2024/11/10/thumb456.jpg\" }" ,
"created_at" : " 2024-11-10T09:15:00.000Z" ,
"sender" : {
"id" : 3 ,
"nickname" : " 이영희"
}
}
],
"total_count" : 45
}
}
코드
설명
200
성공
400
잘못된 채팅방 ID
401
인증 실패
403
채팅방 멤버가 아님
404
채팅방 없음
500
서버 오류
최근 30일 이내의 미디어 메시지만 조회합니다.
최대 30개까지 조회 가능하며, 기본값은 30개입니다.
미디어 메시지는 최신순으로 정렬되어 반환됩니다.
total_count는 전체 미디어 메시지 개수를 제공하여 클라이언트에서 페이징이나 추가 로드 여부를 판단할 수 있습니다.
채팅방 멤버만 조회할 수 있습니다.
GET /chats/{chatRoomId}/messages
채팅방의 메시지 목록을 페이징으로 조회합니다.
파라미터
타입
설명
chatRoomId
number
채팅방 ID
파라미터
타입
필수
설명
cursor
number
선택
페이징 커서 (기본값: 없음)
limit
number
선택
가져올 개수 (1-50, 기본값: 20)
없음
필드
타입
설명
messages[]
array
메시지 목록
messages[].id
number
메시지 ID
messages[].chat_room_id
number
채팅방 ID
messages[].sender_id
number
발신자 ID
messages[].type
string
메시지 타입
messages[].content
string?
메시지 내용
messages[].created_at
string
메시지 발신 시간 (ISO 8601)
messages[].sender
object
발신자 정보
messages[].sender.id
number
발신자 ID
messages[].sender.nickname
string
발신자 닉네임
messages[].sender.profile_img
string?
발신자 프로필 이미지 URL
messages[].mentions[]
array
멘션 목록
messages[].mentions[].id
number
멘션 ID
messages[].mentions[].mentioned_user_id
number
멘션된 사용자 ID
messages[].mentions[].mentionedUser
object
멘션된 사용자 정보
messages[].mentions[].mentionedUser.id
number
멘션된 사용자 ID
messages[].mentions[].mentionedUser.nickname
string
멘션된 사용자 닉네임
hasNext
boolean
다음 페이지 존재 여부
nextCursor
number?
다음 페이지 커서 (없으면 null)
{
"code" : 200 ,
"message" : " 메시지 목록 조회 성공" ,
"data" : {
"messages" : [
{
"id" : 100 ,
"chat_room_id" : 1 ,
"sender_id" : 2 ,
"type" : " text" ,
"content" : " 안녕하세요!" ,
"created_at" : " 2024-01-01T12:00:00.000Z" ,
"sender" : {
"id" : 2 ,
"nickname" : " 김철수" ,
"profile_img" : " http://localhost:3001/uploads-profile/2024/01/15/user2.jpg"
},
"mentions" : []
},
{
"id" : 99 ,
"chat_room_id" : 1 ,
"sender_id" : 3 ,
"type" : " image" ,
"content" : " http://localhost:3001/uploads-chat/2024/11/12/image123_1703123456789_abc123.jpg" ,
"created_at" : " 2024-01-01T11:30:00.000Z" ,
"sender" : {
"id" : 3 ,
"nickname" : " 이영희" ,
"profile_img" : " http://localhost:3001/uploads-profile/2024/01/15/user3.jpg"
},
"mentions" : []
},
{
"id" : 98 ,
"chat_room_id" : 1 ,
"sender_id" : 2 ,
"type" : " video" ,
"content" : " {\" video_url\" :\" http://localhost:3001/uploads-chat-video/2024/11/12/video_1703123456789_def456.mp4\" ,\" thumbnail_url\" :\" http://localhost:3001/uploads-chat-thumbnail/2024/11/12/thumb_1703123456789_def456.jpg\" }" ,
"created_at" : " 2024-01-01T11:00:00.000Z" ,
"sender" : {
"id" : 2 ,
"nickname" : " 김철수" ,
"profile_img" : " http://localhost:3001/uploads-profile/2024/01/15/user2.jpg"
},
"mentions" : []
}
],
"hasNext" : true ,
"nextCursor" : 97
}
}
코드
설명
200
성공
400
잘못된 파라미터
401
인증 실패
403
채팅방 멤버가 아님
404
채팅방 없음
500
서버 오류
메시지는 최신순으로 정렬되어 반환됩니다.
cursor가 없는 경우 가장 최신 메시지부터 조회합니다.
nextCursor로 다음 페이지를 조회할 수 있습니다.
GET /chats/{chatRoomId}/notices
채팅방의 모든 공지사항을 조회합니다.
파라미터
타입
설명
chatRoomId
number
채팅방 ID
파라미터
타입
필수
설명
-
-
-
쿼리 파라미터 없음
없음
필드
타입
설명
[].chat_room_id
number
채팅방 ID
[].user_nickname
string
작성자 닉네임
[].content
string
공지 내용
[].created_at
string
작성 시간 (ISO 8601)
[].updated_at
string
수정 시간 (ISO 8601)
{
"code" : 200 ,
"message" : " 공지사항 목록 조회 성공" ,
"data" : [
{
"chat_room_id" : 1 ,
"user_nickname" : " 관리자" ,
"content" : " 공지사항 내용입니다." ,
"created_at" : " 2024-09-18T02:00:00.000Z" ,
"updated_at" : " 2024-09-18T02:00:00.000Z"
}
]
}
코드
설명
200
성공
400
잘못된 채팅방 ID
401
인증 실패
403
채팅방 멤버가 아님
404
채팅방 없음
500
서버 오류
공지사항은 최신순으로 정렬되어 반환됩니다.
채팅방 멤버만 조회할 수 있습니다.
POST /chats/{chatRoomId}/notices
채팅 내용을 채팅방의 공지사항으로 등록합니다.
파라미터
타입
설명
chatRoomId
number
채팅방 ID
파라미터
타입
필수
설명
-
-
-
쿼리 파라미터 없음
{
"content" : " 공지사항으로 등록할 채팅 내용"
}
필드
타입
필수
설명
content
string
필수
공지사항 내용 (1-1000자)
필드
타입
설명
notice_id
number
등록된 공지사항 ID
success
boolean
작업 성공 여부 (항상 true)
{
"code" : 201 ,
"message" : " 채팅 공지사항 등록 성공" ,
"data" : {
"notice_id" : 5 ,
"success" : true
}
}
{
"code" : 400 ,
"message" : " 잘못된 요청입니다." ,
"errors" : [
{
"field" : " content" ,
"message" : " 공지사항 내용은 빈 값일 수 없습니다."
}
]
}
코드
설명
201
등록 성공
400
유효성 검사 실패
401
인증 실패
403
채팅방 멤버가 아님
404
채팅방 없음
500
서버 오류
공지사항은 자신만 등록할 수 있습니다.
채팅방 멤버만 공지사항을 등록할 수 있습니다.
이전 공지사항들은 유지되고, 새로운 공지사항이 추가됩니다.
PUT /chats/{chatRoomId}
그룹 채팅방의 정보를 수정합니다.
파라미터
타입
설명
chatRoomId
number
채팅방 ID
파라미터
타입
필수
설명
-
-
-
쿼리 파라미터 없음
{
"name" : " 수정된 팀명" ,
"avatar_url" : " http://example.com/new-avatar.jpg"
}
필드
타입
필수
설명
name
string
선택
채팅방 이름 (1-100자)
avatar_url
string
선택
채팅방 아바타 URL (255자 이내)
필드
타입
설명
success
boolean
작업 성공 여부 (항상 true)
{
"code" : 200 ,
"message" : " 채팅방 수정 성공" ,
"data" : {
"success" : true
}
}
코드
설명
200
성공
400
유효성 검사 실패
401
인증 실패
403
권한 없음 (1:1 채팅방 또는 멤버 아님)
404
채팅방 없음
500
서버 오류
1:1 채팅방(private)은 수정할 수 없습니다.
최소 하나의 수정 항목이 필요합니다.
기존 아바타 이미지가 있는 경우 자동으로 삭제됩니다.
POST /chats/{chatRoomId}/avatar-upload
그룹 채팅방의 아바타 이미지를 업로드하고 설정합니다. 기존 아바타가 있는 경우 자동으로 삭제됩니다.
파라미터
타입
설명
chatRoomId
number
채팅방 ID
파라미터
타입
필수
설명
-
-
-
쿼리 파라미터 없음
Request Body (multipart/form-data)
필드
타입
필수
설명
avatar
file
필수
업로드할 아바타 이미지 파일 (JPG, PNG, GIF, WebP 등)
필드
타입
설명
avatar_url
string
업로드된 아바타 이미지의 완전한 URL
path
string
DB에 저장된 경로
filename
string
생성된 고유 파일명
size
number
파일 크기 (bytes)
{
"code" : 200 ,
"message" : " 채팅방 아바타가 설정되었습니다." ,
"data" : {
"avatar_url" : " http://localhost:3001/uploads-chat-avatars/2025/01/15/avatar_1703123456789_abc123.jpg" ,
"path" : " /uploads-chat-avatars/2025/01/15/avatar_1703123456789_abc123.jpg" ,
"filename" : " avatar_1703123456789_abc123.jpg" ,
"size" : 245760
}
}
코드
설명
200
업로드 성공
400
잘못된 파일 형식 또는 파일 없음
401
인증 실패
403
권한 없음 (그룹 채팅방 아님 또는 멤버가 아님)
404
채팅방 없음
413
파일 크기 초과 (10MB)
500
서버 오류
그룹 채팅방(group)만 아바타 설정 가능
채팅방 멤버만 업로드 권한 있음
지원되는 파일 형식: JPG, JPEG, PNG, GIF, WebP, HEIC, HEIF
최대 파일 크기: 10MB
파일은 uploads-chat-avatars/년/월/일/ 폴더에 저장됩니다.
스토리지 분기 : STORAGE_DRIVER 환경변수에 따라 저장소가 결정됩니다
'local': 프로젝트 루트의 로컬 파일시스템에 저장
'naver-cloud': 네이버 클라우드 Object Storage에 저장
기존 아바타 이미지가 있는 경우 자동으로 스토리지에서 삭제됩니다.
두 스토리지 타입 모두 동일한 URL 포맷을 유지하여 API 응답의 일관성을 보장합니다.
상태 코드
설명
200
성공
201
생성 성공
400
잘못된 요청 (유효성 검사 실패 등)
401
인증 실패 (유효하지 않은 토큰)
403
권한 없음 (채팅방 멤버가 아님 등)
404
리소스 없음 (채팅방 없음)
500
서버 오류
최대 2명의 멤버만 참여 가능
name 필드는 항상 null
채팅방 수정 불가
나가기 시 status가 'left'로 변경되어 목록에서 사라지지만 데이터 유지 (재참여 가능)
3명 이상 참여 가능
name 필드 필수 입력
채팅방 수정 가능
모든 API는 JWT 토큰 인증 필요
대체로 채팅방 멤버만 접근 가능
1:1 채팅방 생성 시 상대방 사용자 존재 확인 필요
채팅 파일 업로드 시 스토리지 타입은 환경변수에 따라 결정됩니다.
값
설명
필수 환경변수
'local'
로컬 파일시스템에 저장
BASE_URL
'naver-cloud'
네이버 클라우드 Object Storage에 저장
BASE_URL, NCP_ACCESS_KEY, NCP_SECRET_KEY, NCP_REGION, NCP_ENDPOINT, NCP_BUCKET
환경변수
타입
설명
예시
STORAGE_DRIVER
string
스토리지 타입 ('local' 또는 'naver-cloud')
'naver-cloud'
BASE_URL
string
파일 접근을 위한 기본 URL
'http://localhost:3001'
NCP_ACCESS_KEY
string
네이버 클라우드 액세스 키 (네이버 클라우드 전용)
'your-access-key'
NCP_SECRET_KEY
string
네이버 클라우드 시크릿 키 (네이버 클라우드 전용)
'your-secret-key'
NCP_REGION
string
네이버 클라우드 리전 (네이버 클라우드 전용)
'kr-standard'
NCP_ENDPOINT
string
네이버 클라우드 엔드포인트 (네이버 클라우드 전용)
'https://kr.object.ncloudstorage.com'
NCP_BUCKET
string
네이버 클라우드 버킷 이름 (네이버 클라우드 전용)
'your-bucket-name'
로컬 스토리지 : 프로젝트 루트 디렉토리에 직접 파일 저장
네이버 클라우드 : Object Storage에 파일 저장, 고가용성 및 확장성 제공
URL 일관성 : 두 스토리지 타입 모두 동일한 URL 포맷 사용으로 클라이언트 변경 불필요