서버 URL
서버 | URL |
local | http://localhost:8080/api/ |
dev | http://3.37.54.135:8888/api/ |
prod | https://도메인/api/ |
담당자
담당자 | 도메인 |
Dave | 인증, 사용자 |
Mark | 관리자 |
Jerry | 맵각코 |
Hanjo | 이미지, 모집 게시판 |
enum 값 정의
API 수정 타임라인
도메인 데이터 전체 구조
!!!!!!!!! 주의 !!!!!!!!!
전체적인 구조를 대략적으로만 표현하였습니다. 실제 응답은 하위 문서가 더 정확합니다
도메인 데이터 전체 구조
자기소개
{ "userInfo": { "user": { "userId": Long, "email": String, "name": String, "course": String, "generation": Integer, "role": String, "createdAt": String, "updatedAt": String, }, "introduction": { "introductionId": Long, "profileImgUrl": String, "mbti": String, "blogUrl": String, "githubUrl": String, "summary": String, "latitude": Double, "longitude": Double, "createdAt": String, "updatedAt": String, "likeCount": Long, "isLike": Boolean, "comments": [ { "commentId": Long, "content": String, "createdAt": String, "updatedAt": String, "status": String, "simpleUserInfo": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String }, "children": [ { "commentId": Long, "parent": Long, "content": String, "createdAt": String, "updatedAt": String, "simpleUserInfo": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String } }, ... ] } ] } } }
사용자 간략 정보 (simpleUserInfo)
"simpleUserInfo": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String, }
댓글
"comments": [ { "commentId": Long, "content": String, "createdAt": String, "updatedAt": String, "status": String, "children": [ { "commentId": Long, "parent": Long, "content": String, "createdAt": String, "updatedAt": String, "simpleUserInfo": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String } }, ... ], "simpleUserInfo": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String } }, ... ] ** 주의 : parent 댓글이 삭제되었을 경우(status:DELTETED) parent 댓글의 모든 value는 null로 처리하여 보내줍니다
맵각코 게시글
{ "mapgakco": { "mapgakcoId": Long, "applicantLimit": Integer, "deadline": String, "title": String, "status": String, "content": String, "location": String, "latitude": Double, "longitude": Double, "createdAt": String, "updatedAt": String, "simpleUserInfo": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String, }, "isApplied": Boolean "applicantCount": Integer, "applicants": [ "simpleUserInfo": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String, }, ... ], "comments": [ { "commentId": Long, "content": String, "createdAt": String, "updatedAt": String, "status": String, "children": [ { "commentId": Long, "parent": Long, "content": String, "createdAt": String, "updatedAt": String, "simpleUserInfo": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String } }, ... ], "simpleUserInfo": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String }, }, ... ] } }
모집 게시글
{ "gather": { "gatherId": Long, "applicantLimit": Integer, "deadline": String, "title": String, "status": String, "content": String, "view": Integer, "category": String, "createdAt": String, "updatedAt": String, "simpleUserInfo": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String, }, "isApplied": Boolean, "applicantCount": Integer, "applicants": [ { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String, }, ... ], "comments": [ { "commentId": Long, "content": String, "createdAt": String, "updatedAt": String, "status": String, "simpleUserInfo": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String }, "children": [ { "commentId": Long, "parent": Long, "content": String, "createdAt": String, "updatedAt": String, "simpleUserInfo": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String } }, ... ] }, ... ] } }
목차
에러공통미디어 (media) - 12.08 수정미디어 파일 URL로 반환 (마크다운 작성시)이미지 파일 URL로 반환 (프로필사진) - 12.10 추가됨인증 (auth)로그인 - 12.09 수정JWT Token Refresh 관리자 (admin)코스 추가코스 조회 - 수정예정코스 수정코스 삭제기수 추가기수 조회 - 수정예정기수 수정기수 삭제초대 링크 생성 (UUID 생성)초대 링크 데이터 요청 (링크 진입시)초대 링크 조회 요청사용자 (users)회원가입이메일 중복 확인 - 12.09 수정내 정보 조회 - 12.08 수정내 정보 생성(수정)하기 - 12.08 수정[마이페이지] - 내가 등록한 모임 관리[마이페이지] - 내가 신청한 모임 관리[메인 페이지] 자기소개 추천 - 12.15 수정데둥이 소개 필터링+페이징 조회 (기수/코스/역할) - 12.14 수정데둥이 소개 상세조회 (자기소개) - 12.14 수정좋아요 버튼 클릭좋아요 취소자기소개 댓글 추가 - 12.12 수정자기소개 댓글 수정자기소개 댓글 삭제 - 12.13 수정데둥여지도 조회 (필터링) - 구현완료맵각코 (mapgakco)맵각코 등록 - 12.16 구현완료맵각코 조회 - 12.17 구현완료맵각코 상세 조회 - 12.16 구현완료맵각코 수정 - 12.18 구현완료맵각코 삭제 - 12.16 구현완료맵각코 신청 - 12.16 구현완료맵각코 신청 취소 - 12.16 구현완료맵각코 댓글 추가 - 12.16 구현완료맵각코 댓글 수정 - 12.16 구현완료맵각코 댓글 삭제 - 12.16 구현완료모집 (gathers)모집 게시글 등록 → 구현완료모집 추천 조회 (메인 페이지) - 12.13 추가, 14 수정 → 구현완료모집 게시판 조회 (페이징 조회) - 12.19 수정 → 구현완료모집 게시글 상세 조회 → 구현완료 (RestDocs로 봐주세요)모집 게시글 수정 → 구현완료 (RestDocs로 봐주세요)모집 게시글 삭제 → 구현완료 (RestDocs로 봐주세요)모집 마감 - 12.17 수정 모집 신청 → 구현완료모집 신청 취소 → 구현완료모집 게시글 댓글 추가 - 12.16 수정 → 구현완료모집 게시글 댓글 수정 - 12.16 수정 → 구현완료모집 게시글 댓글 삭제 - 12.14 수정 → 구현완료
에러
공통
Request
모든 요청
Response
{ "message" : String "status" : Integer (status code) "errors" : String "serverTime" : String (서버시간) }
미디어 (media) - 12.08 수정
미디어 파일 URL로 반환 (마크다운 작성시)
Request
POST /api/v1/media Content-Type: multipart/form-data
key | value |
media | 미디어 파일 (이미지, 동영상 등등) |
Response
{ "mediaUrl" : String }
이미지 파일 URL로 반환 (프로필사진) - 12.10 추가됨
Request
POST /api/v1/media/image/profile Content-Type: multipart/form-data
key | value |
profileImage | 이미지 파일 |
Response
{ "imageUrl" : String }
인증 (auth)
로그인 - 12.09 수정
Request
POST /api/v1/auth/login { "email": String, "password": String }
Response
HTTP 200 ok { "token": String, "authority": String }
JWT Token Refresh
Request
POST /api/v1/auth/refresh { "refreshToken": String }
Response
HTTP 200 ok { "token": String, "refreshToken": String, }
관리자 (admin)
코스 추가
Request
POST /api/v1/admin/courses { "name": String }
Response
HTTP 200 ok
코스 조회 - 수정예정
Request
GET /api/v1/admin/courses
Response
{ "courses": [ { "courseId": Long, "name": String }, ... ] }
코스 수정
Request
PUT /api/v1/admin/courses/{courseId} { "name": String }
Response
HTTP 200 ok
코스 삭제
Request
DELETE /api/v1/admin/courses/{courseId}
Response
HTTP 200 ok
기수 추가
Request
POST /api/v1/admin/generations { "sequence": Integer }
Response
HTTP 200 ok
기수 조회 - 수정예정
Request
GET /api/v1/admin/generations
Response
{ "generations" : [ { "generationId" : Long "sequence" : Integer }, ... ] }
기수 수정
Request
PUT /api/v1/admin/generations/{generationId} { "sequence": Integer }
Response
HTTP 200 ok
기수 삭제
Request
DELETE /api/v1/admin/generations/{generationId}
Response
HTTP 200 ok
초대 링크 생성 (UUID 생성)
Request
POST /api/v1/admin/links { "course" : String "generation" : Integer "role" : String "deadline" : (yyyy-MM-DD) }
Response
HTTP 200 ok { "uuid" : String }
초대 링크 데이터 요청 (링크 진입시)
Request
GET /api/v1/admin/links/{uuid} ++ 현재 시각과 deadline 시각을 비교하여 유효하지 않다면 예외처리
Response
HTTP 200 ok { "course" : String "generation" : Integer "role" : String }
초대 링크 조회 요청
Request
GET /api/v1/admin/links
Response
HTTP 200 ok data : [ { "uuid" : uuid, "course" : String, "generation" : Integer, "role" : String, "deadline" : String (yyyy-MM-dd'T'23:59:59) }, ... ]
사용자 (users)
회원가입
Request
POST /api/v1/users { "email": String, "name": String, "password": String, "course": String, "role": String, "generation": Integer }
Response
HTTP 200 ok
이메일 중복 확인 - 12.09 수정
Request
POST /api/v1/users/check { "email": String }
Response
HTTP 200 ok { "isDuplicated": Boolean }
내 정보 조회 - 12.08 수정
Request
GET /api/v1/users/me ** 여기부터 항상 Authentication 헤더에 토큰과 함께 요청
Response
HTTP 200 ok "userInfo": { "user": { "userId": Long, "email": String, "name": String, "course": String, "generation": Integer, "role": String, }, "introduction": { "introductionId": Long, "profileImgUrl": String, "mbti": String, "blogUrl": String, "githubUrl": String, "summary": String,(한 줄 소개) "description": String,(여러 줄 소개) "latitude": Double, "longitude": Double, "updatedAt": String, } }
내 정보 생성(수정)하기 - 12.08 수정
Request
PUT /api/v1/users/me/introduction/{id} { "profileImgUrl": String, "mbti": String, "blogUrl": String, "githubUrl": String, "summary": String, "latitude": Double, "longitude": Double, "content": String }
Response
HTTP 200 ok
[마이페이지] - 내가 등록한 모임 관리
Request
GET /api/v1/users/me/host
Response
{ "gathers": [ { "gatherId": Long, "status": String, "title": String, "category": String, "view": Integer, "deadline": String, "applicantLimit": Integer, "applicantCount": Integer, "createdAt": String }, ... ], "mapgakcos": [ { "mapgakcoId": Long, "status": String, "title": String, "location": String, "meetingDateTime": String, "deadline": String, "applicantLimit": Integer, "applicantCount": Integer, "createdAt": String }, ... ] } ** 프론트에게 알림 : createdAt을 기준으로 카드를 정렬해줘야 합니다.
[마이페이지] - 내가 신청한 모임 관리
Request
GET /api/v1/users/me/applicant
Response
{ "gathers": [ { "gatherId": Long, "status": String "title": String, "category": String, "view": Integer, "deadline": String, "applicantLimit": Integer, "createdAt": String "applicantCount": Integer, }, ... ], "mapgakcos": [ { "mapgakcoId": Long, "status": String "title": String, "location": String, "meetingDateTime": String, "deadline": String, "applicantLimit": Integer, "applicantCount": Integer, "createdAt": String }, ... ] }
[메인 페이지] 자기소개 추천 - 12.15 수정
Request
GET /api/v1/introductions/suggest
Respons
HTTP 200 ok { "cards": [ { "user": { "userId": Long, "name": String, "course": String, "generation": Integer, "role": String, }, "introduction": { "profileImgUrl": String, "mbti": String, "summary": String, "likeCount": Long, "commentCount": Long } }, ... ] } ** 메인페이지에서 자신과 같은 기수/코스 사용자의 자기소개를 랜덤하게 20개 보여줍니다
데둥이 소개 필터링+페이징 조회 (기수/코스/역할) - 12.14 수정
Request
GET /api/v1/introductions?name={String}generation={Integer}&course={String}&role={String}&lastUserId={Long}&size={Integer} ** 필터링 옵션 선택하지 않고 조회시 모든 파라미터 null!! **
Response
HTTP 200 ok { "contents": [ { "user": { "userId": Long, "name": String, "course": String, "generation": Integer, "role": String, }, "introduction": { "introductionId": Long, "profileImgUrl": String, "mbti": String, "summary": String, "likeCount": Long, "commentCount": Long } }, ... ], "lastUserId": Long }
데둥이 소개 상세조회 (자기소개) - 12.14 수정
Request
GET /api/v1/introductions/{id}
Response
HTTP 200 ok { "userInfo": { "user": { "userId": Long, "email": String, "name": String, "course": String, "generation": Integer, "role": String, "createdAt": String, "updatedAt": String, }, "introduction": { "introductionId": Long, "profileImgUrl": String, "mbti": String, "blogUrl": String, "githubUrl": String, "summary": String, "description": String, "latitude": Double, "longitude": Double, "createdAt": String, "updatedAt": String, "likeCount": Long, "isLiked": Boolean, }, "comments": [ { "commentId": Long, "content": String, "createdAt": String, "updatedAt": String, "status": String, "writer": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String }, "children": [ { "commentId": Long, "parent": Long, "content": String, "createdAt": String, "updatedAt": String, "status": String "writer": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String }, "children": null }, ... ] } ] } }
좋아요 버튼 클릭
회원가입과 동시에 자기소개 엔티티가 생성되기 때문에 사용자나 자기소개나 좋아요 상관없을 듯!
Request
POST /api/v1/introductions/{id}/like
Response
HTTP 200 ok { "isLiked": Boolean }
좋아요 취소
Request
DELETE /api/v1/introductions/{id}/like
Response
HTTP 200 ok { "isLiked": Boolean }
자기소개 댓글 추가 - 12.12 수정
Request
POST /api/v1/introductions/{id}/comments { "parentId": Long, "content": String, }
Response
HTTP 200 ok { "commentId": Long, "parentId": Long, }
자기소개 댓글 수정
Request
PATCH /api/v1/introductions/${introductionId}/comments/{commentId} { "content": String, }
Response
HTTP 200 ok
자기소개 댓글 삭제 - 12.13 수정
Request
DELETE /api/v1/introductions/{introductionId}/comments/{commentId} ** DELETE 이지만 comment 테이블의 status 컬럼값을 변경하는것
Response
HTTP 200 ok { content: String(ex: [삭제된 댓글입니다]) }
데둥여지도 조회 (필터링) - 구현완료
Request
GET /api/v1/users/locations?generation={Integer}&course={String} ** generation, course의 default는 해당 사용자의 값으로 보내준다
Response
"users":[ { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "latitude": Double, "longitude": Double }, ... ]
맵각코 (mapgakco)
맵각코 등록 - 12.16 구현완료
Request
POST /api/v1/mapgakcos { "title": String, "applicantLimit": Integer, "deadline": String, "content": String, "location": String, "latitude": Double, "longitude": Double, "meetingAt": String, }
Response
HTTP 200 ok { "status": String }
맵각코 조회 - 12.17 구현완료
Request
GET /api/v1/mapgakcos { "lastCoordinate": { "northEastX": Double, "northEastY": Double, "southWestX": Double, "southWestY": Double }, "currentCoordinate": { "northEastX": Double, "northEastY": Double, "southWestX": Double, "southWestY": Double } } ** 메인페이지에서 보여질 경우 중심점 : 서초대륭타워 ** 맵각코 서비스에서 보여질 경우 중심점 - 내 위치 등록한 경우 : 내 위치 - 등록하지 않은 경우 : 서초대륭타워
Response
HTTP 200 ok { "mapgakcos": [ { "mapgakcoId": Long, "status": String "title": String, "location": String, "latitude": Double, "longitude": Double, "simpleUserInfo": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String, } }, ... ] } ** 커서 페이징 형식으로 데이터 반환
맵각코 상세 조회 - 12.16 구현완료
Request
GET /api/v1/mapgakcos/{id}
Response
{ "mapgakco": { "mapgakcoId": Long, "applicantLimit": Integer, "applicantCount": Integer, "deadline": String, "title": String, "status": String, "content": String, "location": String, "latitude": Double, "longitude": Double, "meetingAt": String, "createdAt": String, "updatedAt": String, "writer": { // simpleUserInfo "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String, }, "applicants": [ "simpleUserInfo": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String, }, ... ], "comments": [ { "commentId": Long, "content": String, "createdAt": String, "updatedAt": String, "status": String, "children": [ { "commentId": Long, "parent": Long, "content": String, "createdAt": String, "updatedAt": String, "simpleUserInfo": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String } }, ... ], "simpleUserInfo": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String }, }, ... ] } }
맵각코 수정 - 12.18 구현완료
Request
PATCH /api/v1/mapgakcos/{id} { "title": String, "content": String, "location": String, "latitude": Double, "longitude": Double, "meetingAt": String } ** 위치 수정 화면 시나리오 : 내거면 언제든지 수정 가능
Response
HTTP 200 ok { "status": String } ** 상태가 변경되면 프론트엔드에서 어떻게 반영하나요?
맵각코 삭제 - 12.16 구현완료
Request
DELETE /api/v1/mapgakcos/{id} ** DELETE지만 상태만 변경
Response
HTTP 200 ok
맵각코 신청 - 12.16 구현완료
Request
POST /api/v1/mapgakcos/{id}/apply
Response
HTTP 200 ok { "status": String } ** 상태 종류 - 모집중 (GATHERING) - 모집마감 (CLOSED) - 등록자가 직접 마감 누름 - 마감 기간 초과시 자동 마감 - 인원 초과 (FULL) - 삭제 (DELETED)
맵각코 신청 취소 - 12.16 구현완료
Request
DELETE /api/v1/mapgakcos/{id}/apply ** 실제로 데이터 삭제
Response
HTTP 200 ok
맵각코 댓글 추가 - 12.16 구현완료
Request
POST /api/v1/mapgakcos/{id}/comments { "parent": Long, "content": String, }
Response
HTTP 200 ok { "commentId": Long, "parentId": Long, }
맵각코 댓글 수정 - 12.16 구현완료
Request
PATCH /api/v1/mapgakcos/{mapgakcoId}/comments/{commentId} { "content": String, }
Response
HTTP 200 ok
맵각코 댓글 삭제 - 12.16 구현완료
Request
DELETE /api/v1/mapgakcos/{mapgakcoId}/comments/{commentId} ** DELETE 이지만 comment 테이블의 status 컬럼값을 변경하는것
Response
HTTP 200 ok
모집 (gathers)
모집 게시글 등록 → 구현완료
Request
POST /api/v1/gathers { "title": String, "applicantLimit": Integer, "deadline": String, "content": String, "category": String, }
Response
HTTP 200 ok { "status": String }
모집 추천 조회 (메인 페이지) - 12.13 추가, 14 수정 → 구현완료
Request
GET /api/v1/gathers/suggest ** 가장 최신에 올라온 모집 게시글 상위 5개의 정보를 제공
Response
{ "gathers": [ { "gatherId": Long, "status": String "title": String, "category": String, "view": Integer, "deadline": String, "applicantLimit": Integer, "applicantCount": Integer, "commentCount" : Integer, "author": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String, } }, ... ] }
모집 게시판 조회 (페이징 조회) - 12.19 수정 → 구현완료
Request
GET /api/v1/gathers?title={String}?category={String}&lastId={Long}&size={Integer} ** category==null일 경우 자동으로 전체조회될 것 같음. 즉, ALL이라는 키워드는 필요 없을 것 ** 페이징 첫 요청일 경우 lastId는 null로 요청하면 됩니다.
Response
{ "values": [ { "gatherId": Long, "status": String "title": String, "category": String, "view": Integer, "deadline": String, "applicantLimit": Integer, "applicantCount": Integer, "commentCount" : Integer, "author": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String, } }, ... ] }
모집 게시글 상세 조회 → 구현완료 (RestDocs로 봐주세요)
Request
GET /api/v1/gathers/{id}
Response
{ { "gatherId": Long, "applicantLimit": Integer, "deadline": String, "title": String, "status": String, "content": String, "view": Integer, "category": String, "createdAt": String, "updatedAt": String, "author": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String, }, "isApplied": Boolean, "applicantCount": Integer, "participants": [ { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String, }, ... ], "comments": [ { "commentId": Long, "content": String, "createdAt": String, "updatedAt": String, "status": String, "author": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String }, "subComment": [ { "commentId": Long, "parent": Long, "content": String, "createdAt": String, "updatedAt": String, "author": { "userId": String, "name": String, "course": String, "generation": Integer, "profileImgUrl": String, "role": String } }, ... ] }, ... ] } }
모집 게시글 수정 → 구현완료 (RestDocs로 봐주세요)
Request
PATCH /api/v1/gathers/{id} { "title": String, "deadline": String, "content": String, "applicantLimit": Integer, }
Response
HTTP 200 ok { "status": String }
모집 게시글 삭제 → 구현완료 (RestDocs로 봐주세요)
Request
DELETE /api/v1/gathers/{id} ** DELETE지만 상태만 변경
Response
HTTP 200 ok
모집 마감 - 12.17 수정
Request
PATCH /api/v1/gathers/{gatherId}/close
Response
HTTP 200 ok { "status": String }
모집 신청 → 구현완료
Request
POST /api/v1/gathers/{id}/apply
Response
HTTP 200 ok
모집 신청 취소 → 구현완료
Request
DELETE /api/v1/gathers/{id}/apply ** 이건 실제로 gather_applicant 테이블에서 삭제
Response
HTTP 200 ok
모집 게시글 댓글 추가 - 12.16 수정 → 구현완료
Request
POST /api/v1/gathers/{id}/comments { "parentId": Long, "content": String, } ** parentId는 부모 댓글의 id값입니다. (대댓글일 경우에만 있습니다.) 대댓글이 아닌 경우는 null로 요청하면 됩니다.
Response
HTTP 200 ok { "commentId": Long, "parentId": Long, }
모집 게시글 댓글 수정 - 12.16 수정 → 구현완료
Request
PATCH /api/v1/gathers/{gatherId}/comments/{commentId} { "content": String, }
Response
HTTP 200 ok { "modifiedAt" : String }
모집 게시글 댓글 삭제 - 12.14 수정 → 구현완료
Request
DELETE /api/v1/gathers/{gatherId}/comments/{commentId} * 실제로 삭제 X -> 상태만 변경
Response
HTTP 200 ok { "content": String (삭제된 댓글입니다) }