Skip to content

[REFACTOR/CHAT] 채팅 서비스 API 명세서 변경안 #37

@Cassiiopeia

Description

@Cassiiopeia

📌 API 명세서 업데이트

✨ Description

기본적인 인증 처리

  • Authorization: Bearer "토큰값"

1. 채팅방 생성 또는 조회

  • 방식: POST
  • Endpoint: {{baseurl}}/chat/room
  • Headers:
    • Authorization: Bearer "토큰값"
    • Content-Type: application/json
  • Params:
    • recipientId: "수신자의 Member ID"
  • Response:
{
  "chatRoomId": "생성된 채팅방 ID",
  "memberIdList": ["참여자 ID 목록"],
  "lastChatMessageContent": "최근 채팅 메시지 내용",
  "lastChatMessageAt": "최근 채팅 메시지 시각"
}

2. 회원별 채팅방 목록 전체 조회

  • 방식: GET
  • Endpoint: {{baseurl}}/chat/member/room-list
  • Headers:
    • Authorization: JWT토큰
  • Response:
[
  {
    "chatRoomId": "채팅방 ID",
    "memberIdList": ["참여자 ID 목록"],
    "lastChatMessageContent": "최근 채팅 메시지 내용",
    "lastChatMessageAt": "최근 채팅 메시지 시각"
  },
    {
    "chatRoomId": "채팅방 ID",
    "memberIdList": ["참여자 ID 목록"],
    "lastChatMessageContent": "최근 채팅 메시지 내용",
    "lastChatMessageAt": "최근 채팅 메시지 시각"
  }
]

3. 채팅방 내 채팅내역 조회

  • 방식: GET
  • Endpoint: {{baseurl}}/chat/room/{chatRoomId}/message-list
  • Headers:
    • Authorization: Bearer "토큰값"
  • Path Variables:
    • chatRoomId: "1_2"
  • Query Params:
    • page: 0 (default)
    • size: 20 (default)
  • Response:
[
  {
    "chatMessageId": "채팅 메시지 ID",
    "chatRoomId": "채팅방 ID",
    "senderId": "보낸 사람 ID",
    "content": "메시지 내용",
    "imageUrlList": ["이미지 URL 목록"],
    "createdAt": "생성 시각"
  },
    {
    "chatMessageId": "채팅 메시지 ID",
    "chatRoomId": "채팅방 ID",
    "senderId": "보낸 사람 ID",
    "content": "메시지 내용",
    "imageUrlList": ["이미지 URL 목록"],
    "createdAt": "생성 시각"
  }
]

4. 채팅방 정보 업데이트

  • 방식: PUT
  • Endpoint: {{baseurl}}/chat/room-list/{chatRoomId}
  • Headers:
    • Authorization: Bearer "토큰값"
  • Path Variables:
    • chatRoomId: "1_2"
  • Response:
{
  "chatRoomId": "채팅방 ID",
  "memberIdList": ["참여자 ID 목록"],
  "lastChatMessageContent": "최근 채팅 메시지 내용",
  "lastChatMessageAt": "최근 채팅 메시지 시각"
}

5. 메시지 전송 (웹소켓)

  • 방식: STOMP 프로토콜

  • 경로 설명:

    Client -> Server: STOMP 프로토콜을 통해 "/chatapp/room/{chatRoomId}/message" 경로로 메시지 전송

    Server -> @MessageMapping("/room/{chatRoomId}/message")로 메시지 받음

    -> SimpMessagingTemplate 사용 -> "/chatrooms/{chatRoomId}" 경로로 메시지 게시 (publish)

    메시지 -> ("/chatrooms/{chatRoomId}")를 구독하고 있는 Client에게 전달됨

  • 이미지 전송 방식:

    클라이언트에서는 MultipartFile을 사용하지 않습니다. 이는 주로 HTTP 프로토콜에서 사용하는 방법이며 WebSocket에서는 바이너리 데이터 전송을 지원하지만 멀티파트 폼 데이터를 기본적으로 지원하지 않습니다. 따라서 Base64 인코딩을 사용하여 바이너리 데이터(이미지, 오디오, 비디오 등)를 텍스트 형태로 변환하여 네트워크를 통해 안전하게 파일을 전송합니다.

  • client에서 메시지 전송 JSON:

{
  "content": "메시지 내용",
  "imageBase64List": [
    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA...",
    "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAAAAAAAD..."
  ]
}
  • client (프론트) 가 JSON 객체 -> STOMP 프로토콜을 사용 -> 서버의 endpoint로 전송합니다.

  • WebSocketConfig에서 설정한 MappingJackson2MessageConverter는 클라이언트로부터 받은 JSON 메시지를 자동으로 객체로 매핑합니다. -> 컨트롤러에서 @RequestBody 어노테이션을 사용할 필요가 없습니다. ( STOMP 메시지를 처리할 때 JSON 데이터가 자동매핑 )

  • 설명

    Client(프론트) -> JSON 형태로 메시지, Base64 인코딩된 이미지 데이터
    -> WebSocket -> sever로 전송

    @MessageMapping을 사용한 메서드이므로
    JSON 데이터가 자동으로 해당 Java 객체로 매핑되어 처리됩니다.

    SimpMessagingTemplate -> 메시지 -> 해당 채팅방을 구독하는 client로 전송

6. 채팅방 내 채팅 메시지가 없을 경우 채팅방 삭제

  • 방식: DELETE

  • Endpoint: {{baseurl}}/chat/room/check-empty/{chatRoomId}

  • Headers:

    • Authorization: Bearer "토큰값"
  • Path Variables:

    • chatRoomId: "1_2"
  • Response: No Content

7. 채팅방 삭제

  • 방식: DELETE

  • Endpoint: {{baseurl}}/chat/room/{chatRoomId}

  • Headers:

    • Authorization: Bearer "토큰값"
  • Path Variables:

    • chatRoomId: "1_2"
  • Response: No Content

8. 웹소켓 연결시 JWT 토큰 인증 방식 추가

  • 기존 STOMP 프로토콜을 이용하여 WebSocket 연결시 아무런 검증 로직이 없었습니다.

로직을 추가하여 Client측에서 WebSocket 을 연결전에 jwt 토큰을 header에 추가해서 검증과정을 거쳐야 웹소켓 연결이 시작됩니다.

: WebSocketConfig 및 JwtUtil에서는 "Access-Token"이라는 정확한 문자열 값을 사용하여 액세스 토큰을 추출하고 있습니다. 따라서 프론트엔드에서도 동일한 키를 사용해야 합니다.

일반적인 HTTP 요청에서 사용되는 "Authorization": "Bearer " 형태와는 다르게

WebSocket 설정에서는 "Access-Token": "" 형태로 토큰을 전송합니다. 따라서 "Authorization" 키 대신 "Access-Token" 키를 사용해야 하며, "Bearer " 접두사 없이 토큰 값만을 직접 전달해야 합니다.

// WebSocket 연결 설정
const sock = new SockJS('/ws');
const stompClient = Stomp.over(sock);

// WebSocket 연결
stompClient.connect({
    "Access-Token": "여기에_유효한_접근_토큰"
}, function onConnect(frame) {

## To Reviewers 질문 환영합니다!

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentation

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions