클러치 서비스의 어플리케이션 서버이다.
서버 언어로는 Node.js를 사용하며, ExpressJs 및 ejs를 사용하여 API와 웹 백엔드를 구축한다. 데이터베이스 엔진으로는 MongoDB, 드라이버로는 mongoose를 사용한다.
클라이언트단에서 서버로의 모든 호출은 비동기식으로 이루어지며(Asynchronize), 서버는 그 요청을 처리해 JSON 형태의 결과값을 HTTP 응답 형태(application/json)로 반환한다.
서버에서 각각의 REST 메서드와 클라이언트의 인터페이스 메서드는 서로 대응된다.
Main URL : http://dev.thedeblur.com:1129
서비스 오픈 전까지 임시로 Deblur의 개발서버를 사용한다.
다음과 같은 명령어들이 존재한다.
GET
: 해당 리소스를 가져오거나, 리스팅한다.
POST
: 해당 리소스를 생성한다.
PATCH
: 해당 리소스를 수정한다.
PATCH
: 해당 리소스를 수정한다.
PUT
: 해당 리소스에 파일을 업로드한다.
헤더를 사용하는 경우는 접근이 제한된 리소스를 인증할 때(token) 빼고는 없으며, 대부분의 파라미터는 GET에서는 Query(x=1&y=2)로, POST, PATCH, DELETE에서는 FormUrlEncoded로 전달된다.
Response의 타입은 무조건 application/json이며, API 호출 결과인 status라는 항목을 포함한다.
{ "status" : { "code" : "200", "message" : "성공" }, "key" : “value", "key" : “value”, (....) }
Code | Status | Message |
---|---|---|
200 | SUCCEED | 성공 |
400 | FAILED | 실패 (서버 내부 오류) |
411 | FAILED_LESS_PARAMETER | 파라미터 부족 |
1000 | FAILED_DB_CONNECTION | 데이터베이스 내부 오류 |
401 | FAILED_NO_PERMISSION | 권한 부족 |
402 | FAILED_TOKEN_INVALID | Auth 토큰 불일치 |
1001 | FAILED_ACCOUNT_INVALID | 계정 불일치 |
1002 | FAILED_ALREADY_EXISTS | 아이디가 이미 존재 |
이 코드들은 클라이언트의 Clutch.Status 클래스와 서버의 status.json에 모두 정의되어 있다.
###METADATA STORE
PUT
/picturesGET
/pictures/full/:metadataIdGET
/pictures/thumb/:metadataIdGET
/pictures/custom/:metadataId/:width/:height
###USER
POST
/user/registerPOST
/user/loginGET
/user/:idGET
/user/:id/picturePOST
/user/:id/pictureGET
/user/:id/starPOST
/user/:id/starGET
/user/:id/followersGET
/user/:id/followingsPOST
/user/:id/followingsDELETE
/user/:id/followingsPATCH
/user/:idPATCH
/user/:id/starDELETE
/user/:id
###Clutch
GET
/clutchPOST
/clutchDELETE
/clutch/:idPOST
/clutch/:id/likeGET
/clutch/:id/commentsPOST
/clutch/:id/commentsDELETE
/clutch/:id/comments/:commentId
###Clutch Book
GET
/user/:id/cbPOST
/user/:id/cbGET
/user/:id/cb/:cbIdPUT
/user/:id/cb/:cbIdDELETE
/user/:id/cb/:cbIdGET
/user/:id/cb/:cbId/followersGET
/user/:id/cb/:cbId/followingsPOST
/user/:id/cb/:cbId/followings
###Community
GET
/communityPOST
/community/:articleId/PUT
/community/:articleId/DELETE
/community/:articleId/POST
/community/:articleId/likeGET
/community/:articleId/GET
/community/:articleId/commentsPOST
/community/:articleId/commentsDELETE
/community/:articleId/comments/:commentId
###Artist
GET
/artist/:artistId/
###Notification
GET
/notifications/meGET
/notifications/friends
###Ranking
GET
/ranking/GET
/ranking/:date/details
###Settings
GET
/user/:id/settings/:keyPOST
/user/:id/settings/:key
유저의 개인적인 정보에 접근하고 수정하기 위해선 인증이 필요한데, 이때 토큰이 필요하다.
유저의 공개적인 정보(프로필)에 접근하기 위해서는 유저의 고유번호인 User ID를 알아야 한다.
토큰은 HTTP Request의 Header에 token이란 필드에 들어가며, userId는 URL 자체에 경로로 들어간다.
그러므로 토큰과 유저ID는 로그아웃 전까지 클라이언트의 저장소에 임시로 저장해야 한다.
========
유저가 Clutch 서비스에 회원가입할 때 사용됩니다.
picture 필드를 채울땐 먼저 메타데이터 스토어에 이미지를 업로드 한 뒤 Metadata ID를 주면 됩니다.
Name | Type | Description |
---|---|---|
String | 이메일 주소 | |
pw | String | 패스워드 (MD5 해싱 필수!) |
name | String | 유저 프로필의 상태 메세지 |
status_message | String | 유저 프로필의 상태 메세지 |
picture | String | 유저의 프로필 사진 (Metadata ID) |
gender | Number | 성별 (남자=0, 여자=1) |
Name | Description |
---|---|
userToken | 유저의 토큰. 개인정보 접근시 인증에 사용된다. |
userId | 유저의 고유번호. 공개적인 정보 접근에 사용됨. |
Code | Status | Message |
---|---|---|
200 | SUCCESS | 성공 |
1002 | REGISTER_ACOUNT_EXISTS | 이메일 중복 |
POST /user/register
email=test@clutch.com
pw=5d41402abc4b2a76b9719d911017c592 // MD5("hello")
status_message=Hello
picture=(none)
gender=0
>>>>>>>>>>
{
status: { code: 200, message: "성공" },
userId: (User ID),
userToken: (user Token)
}
========
유저가 Clutch 서비스에 로그인할 때 사용됩니다.
Name | Type | Description |
---|---|---|
String | 이메일 주소 | |
pw | String | 패스워드 (MD5 해싱 필수!) |
Name | Description |
---|---|
userToken | 유저의 토큰. 개인정보 접근시 인증에 사용된다. |
userId | 유저의 고유번호. 공개적인 정보 접근에 사용됨. |
Code | Status | Message |
---|---|---|
200 | SUCCESS | 성공 |
1001 | LOGIN_FAILED_ACCOUNT_MISMATCH | 계정 불일치 |
POST /user/login email=test@clutch.com pw=5d41402abc4b2a76b9719d911017c592 // MD5("hello") >>>>>>>>>> { status: { code: 200, message: "성공" }, userId: (User ID), userToken: (user Token) }
========
한 유저의 프로필을 얻어올 때 사용된다.
Name | Type | Description |
---|---|---|
id | String | 원하는 유저의 ID |
Name | Description |
---|---|
profile | 유저의 프로필 (JSON 객체) |
profile.name | 이름 |
profile.status_message | 유저 프로필의 상태 메세지 |
profile.picture | 유저의 프로필 사진 (Metadata ID) |
profile.followers_count | 팔로워들의 수 |
profile.followings_count | 팔로잉하는 수 |
profile.gender | 성별 (남자=0, 여자=1) |
profile.last_photos | 유저의 대표 사진 5개 (Metadata ID) |
GET /user/52ff32f5ce6c300f55000003 >>>>>>>>>> { status: { code: 200, message: "성공" }, profile: { name: "김료준", status_message: "안뇽안뇽~", picture: "(no pic)", followers_count: 3, followings_count: 0, gender: 0, last_photos: [] } }
========
한 유저의 프로필 사진을 얻어올 때 사용된다.
Name | Type | Description |
---|---|---|
id | String | 원하는 유저의 ID |
x | Number | (옵션) 원하는 사진의 가로크기 |
y | Number | (옵션) 원하는 사진의 세로크기 |
Content-Type: image/jpeg
Body: (프로필 사진)
GET /user/52ff32f5ce6c300f55000003/picture?x=300&y=300 >>>>>>>>>> Content-Type: image/jpeg Body: (프로필 사진)
========
한 유저의 프로필 사진을 바꿀 때 사용된다.
Name | Description |
---|---|
token | 유저의 토큰 |
Name | Type | Description |
---|---|---|
id | String | 원하는 유저의 ID |
picture | (multipart) File | 프로필 이미지 파일 |
PUT /user/52ff32f5ce6c300f55000003/picture >>>>>>>>>> { status: { code: 200, message: "성공" }}
========
Name | Type | Description |
---|---|---|
id | String | 원하는 유저의 ID |
Name | Description |
---|---|
star | 풍선 갯수 |
GET /user/52ff32f5ce6c300f55000003/star >>>>>>>>>> { status: { code: 200, message: "성공" }, stars: 0 }
========
Name | Description |
---|---|
token | 유저의 토큰 |
Name | Type | Description |
---|---|---|
id | String | 원하는 유저의 ID |
count | Number | 주기를 원하는 풍선 갯수 |
POST /user/52ff32f5ce6c300f55000003/star >>>>>>>>>> { status: { code: 200, message: "성공" } }
========
유저의 팔로어 목록을 구한다. 리스트 형식으로 Response한다.
Name | Type | Description |
---|---|---|
id | String | 원하는 유저의 ID |
pageNo | Number | 몇번째 페이지의 결과를 원하는가 |
pageCount | Number | 한페이지에 몇개의 결과를 넣는가 |
Name | Description |
---|---|
followers | 팔로어 배열 |
followers.id | 팔로어 ID |
followers.name | 팔로어 이름 |
followers.status_message | 팔로어 상태 메세지 |
followers.picture | 팔로어 프로필 사진 ID |
followers.followers_count | 팔로어의 팔로어 명수 |
followers.followings_count | 팔로어의 팔로잉 명수 |
followers.gender | 팔로어의 팔로잉 명수 |
followers.last_photos[] | 팔로어의 대표 사진 5장 |
GET /user/52ff32f5ce6c300f55000003/followers?pageNo=0&pageCount=50 >>>>>>>>>> { status: { code: 200, message: "성공" }, followers: [ { id: 52ff32f5ce6c300f55000014, name: "김유저", status_message: "유저1입니다. 안뇽~", picture: (no pic), followers_count: 0, followings_count: 1, gender: 1, last_photos: [a,b,c,d,e] }, { id: 6a6831f4ce6c300f55000025, name: "박유저", status_message: "유저2입니다. 안뇽~", picture: (no pic), followers_count: 51, followings_count: 1, gender: 0, last_photos: [b,C,a,D,x] } ] }
========
Name | Type | Description |
---|---|---|
id | String | 원하는 유저의 ID |
pageNo | Number | 몇번째 페이지의 결과를 원하는가 |
pageCount | Number | 한페이지에 몇개의 결과를 넣는가 |
Name | Description |
---|---|
followings | 팔로잉 배열 |
followings.id | 팔로잉의 ID |
followings.name | 팔로잉 이름 |
followings.status_message | 팔로잉의 상태 메세지 |
followings.picture | 팔로잉의 프로필 사진 ID |
followings.followers_count | 팔로잉의 팔로어 명수 |
followings.followings_count | 팔로잉의 팔로잉 명수 |
followings.gender | 팔로잉의 팔로잉 명수 |
followings.last_photos[] | 팔로잉의 대표 사진 5장 |
GET /user/52ff32f5ce6c300f55000003/followings?pageNo=0&pageCount=50 >>>>>>>>>> { status: { code: 200, message: "성공" }, followings: [ { id: 52ff32f5ce6c300f55000014, name: "김유저", status_message: "유저1입니다. 안뇽~", picture: (no pic), followers_count: 0, followings_count: 1, gender: 1, last_photos: [a,b,c,d,e] }, { id: 6a6831f4ce6c300f55000025, name: "박유저", status_message: "유저2입니다. 안뇽~", picture: (no pic), followers_count: 51, followings_count: 1, gender: 0, last_photos: [b,C,a,D,x] } ] }
========
Name | Description |
---|---|
token | 유저의 토큰 |
Name | Type | Description |
---|---|---|
id | String | 유저의 ID |
following_id | String | 팔로우를 원하는 유저의 ID |
POST /user/52ff32f5ce6c300f55000003/followings >>>>>>>>>> { status: { code: 200, message: "성공" } }
========
Name | Description |
---|---|
token | 유저의 토큰 |
Name | Type | Description |
---|---|---|
id | String | 유저의 ID |
following_id | String | 팔로우 해제를 원하는 유저의 ID |
DELETE /user/52ff32f5ce6c300f55000003/followings >>>>>>>>>> { status: { code: 200, message: "성공" } }
========
Name | Description |
---|---|
token | 유저의 토큰 |
Name | Description |
---|---|
id | 유저의 ID |
name | 이름 |
status_message | 유저 프로필의 상태 메세지 |
picture | 유저의 프로필 사진 (Metadata ID) |
gender | 성별 (남자=0, 여자=1) |
pw | 패스워드 (MD5 해싱 필수!) |
PATCH /user/52ff32f5ce6c300f55000003 name="김료준" status_message="수정된 상태 메세지!" pw='24b7059cb0f4df701401ddf854d770ee' // MD5("Halloo") >>>>>>>>>> { status: { code: 200, message: "성공" } }
========
회원을 탈퇴하고 DB에서 모든 데이터를 지웁니다.
Name | Description |
---|---|
token | 유저의 토큰 |
DELETE /user/52ff32f5ce6c300f55000003/followings >>>>>>>>>> { status: { code: 200, message: "성공" } }
모든 클러치는 클러치북에 존속된다. 그렇다고 클러치의 리소스는 클러치북 안에 속해있지 않으며 독자적이다. (/clutch) 또한, 자신이 클러치를 올리고 좋아요를 누르는 등의 기타 행동들은 모두 자신의 팔로워들에게 알림이 전달된다. **또한 클러치와 관련된 모든 활동들은 Header의 token을 통한 유저 인증이 필요하지만 문서에는 전부 중복 기재하지 않겠다. 이것은 기본 요구사항이다. **
Name | Description |
---|---|
tags | 클러치에 들어가는 태그들 (쉼표로 구분) |
cb_id | 이 클러치가 속하는 클러치북 ID |
content_type | 사진: 0, 동영상: 1, 링크: 2 |
content_pictures | (사진일 경우) 사진의 메타데이터 ID들 (공백으로 구분) |
content_link | (동영상/링크일 경우) 해당하는 URL |
content_body | 글 내용 |
Name | Description |
---|---|
clutchId | 이 클러치의 ID |
POST /clutch cb_id="30501304" tags="존예,여신,걸스데이"" content_type=0 content_pictures="pic1id pic2id pic3id" content_body="민아 존예..." >>>>>>>>>> { status: { code: 200, message: "성공" }, clutchId: fa4230491alf }
========
Name | Description |
---|---|
sort | 정렬. (0: 인기순, 1: 최신순) |
pageNo | 요청하는 페이지 번호 |
pageCount | 한 페이지당 로딩할 클러치 갯수 |
Name | Description |
---|---|
clutches | 로딩된 클러치 목록(리스트) |
clutches.clutchId | 이 클러치의 ID |
clutches.cb_id | 클러치북의 ID |
clutches.cb_name | 클러치북 이름 |
clutches.userId | 클러치를 올린 유저의 ID |
clutches.userName | 클러치를 올린 유저의 이름 |
clutches.userPhoto | 클러치를 올린 유저의 프로필 사진 |
clutches.content_type | 클러치 종류 |
clutches.content_pictures | (옵션, 사진만) 사진들 (공백으로 구분) |
clutches.content_link | (옵션, 동영상 및 링크만) 링크 URL |
clutches.content_link_thumb | (옵션, 동영상 및 링크만) 링크 썸네일 이미지 |
GET /clutch sort=0 pageNo=0 pageCount=50 >>>>>>>>>> { status: { code: 200, message: "성공" }, clutches: [ { clutchId: "fa4230491alf", cb_id: "fa4230491alf", cb_name: "걸스데이", userId: "fa4230491alf", userName: "신광수", userPhoto: "(no pic)", content_type: 0, content_pictures: "pic1id pic2id" }, { clutchId: "fa4230491alf", cb_id: "fa4230491alf", cb_name: "소녀시대", userId: "fa4230491alf", userName: "이호연" userPhoto: "(no pic)", content_type: 1, content_link: "http://thedeblur.com:1129/videos/1934205" content_link_thumb: "(no pic)" } ] }
========
Name | Description |
---|---|
clutchId | 지우고 싶은 클러치의 ID |
DELETE /clutch/fa4230491alf >>>>>>>>>> { status: { code: 200, message: "성공" } }
========
Name | Description |
---|---|
clutchId | 좋아하는 클러치의 ID |
POST /clutch/fa4230491alf/like >>>>>>>>>> { status: { code: 200, message: "성공" } }
========
Name | Description |
---|---|
clutchId | 좋아요를 해제할 클러치의 ID |
DELETE /clutch/fa4230491alf/unlike >>>>>>>>>> { status: { code: 200, message: "성공" } }
========
Name | Description |
---|---|
clutchId | 댓글을 가져올 클러치의 ID |
pageNo | 요청하는 페이지 번호 |
pageCount | 한 페이지당 로딩할 댓글 갯수 |
Name | Description |
---|---|
comments | 로딩된 댓글 목록 |
comments.commentId | 이 클러치의 ID |
comments.userId | 댓글을 쓴 유저의 ID |
comments.userName | 댓글을 쓴 유저의 이름 |
comments.userPhoto | 댓글을 쓴 유저의 프로필 사진 |
comments.body | 댓글 내용 |
comments.date | 댓글을 쓴 시간 (Timestamp) |
comments.likeCount | 댓글이 받은 추천 갯수 |
comments.unlikeCount | 댓글이 받은 비추천 갯수 |
GET /clutch/fa4230491alf/comments pageNo=0 pageCount=50 >>>>>>>>>> { status: { code: 200, message: "성공" }, comments: [ { commentId: "fa4230491alf", userId: "fa4230491alf" userName: "김효준", userPhoto: "(no pic)", body: "와... 정말 예쁘네요", likeCount: 0, unlikeCount: 0, date: 1292667739248 }, { commentId: "fa4230491alf", userId: "fa4230491alf", userName: "홍길동", userPhoto: "(no pic)", body: "진심 너무 예쁘네요", likeCount: 1, unlikeCount: 0, date: 1392667736248 }] }
========
Name | Description |
---|---|
clutchId | 댓글 삭제의 대상이 되는 클러치의 ID |
commentId | 삭제할 댓글의 ID |
DELETE /clutch/fa4230491alf/comments/104059/delete >>>>>>>>>> { status: { code: 200, message: "성공" } }
========
DELETE 명령어를 통해 추천을 해제할 수 있다.
Name | Description |
---|---|
clutchId | 댓글 추천의 대상이 되는 클러치의 ID |
commentId | 추천할 댓글의 ID |
Code | Status | Message |
---|---|---|
2002 | ALREADY_UNLIKED | 이미 비추천을 누른 상태임 |
POST /clutch/fa4230491alf/comments/104059/like >>>>>>>>>> { status: { code: 2002, message: "이미 비추천을 누르셨습니다." } }
========
DELETE 명령어를 통해 비추천을 해제할 수 있다.
Name | Description |
---|---|
clutchId | 댓글 추천의 대상이 되는 클러치의 ID |
commentId | 추천할 댓글의 ID |
Code | Status | Message |
---|---|---|
2001 | ALREADY_LIKED | 이미 추천을 누른 상태임 |
POST /clutch/fa4230491alf/comments/104059/like >>>>>>>>>> { status: { code: 2001, message: "이미 추천을 누르셨습니다." } }
모든 클러치는 클러치북에 존속된다. 클러치북의 리소스는 유저 안에 속해있다. (/user/:userId/cb)
또한, 클러치북을 지칭할때는 clutchbook이 아닌 cb로 지칭한다.
Name | Description |
---|---|
name | 클러치북 이름 |
desc | 클러치북 설명 |
coverPics | 클러치북 커버들 |
tags | 들어가는 태그들 (쉼표로 구분) |
Name | Description |
---|---|
cb_id | 이 클러치북의 ID |
POST /user/fa4230491alf/cb name="걸스데이" desc="걸스데이 사진 저장하는 곳!" tags="존예,여신,걸스데이"" >>>>>>>>>> { status: { code: 200, message: "성공" }, cb_id: fa4230491alf }
========
Name | Description |
---|---|
cb_id | 지우려는 클러치북 ID |
DELETE /user/fa4230491alf/cb/aa31347f >>>>>>>>>> { status: { code: 200, message: "성공" } }
========
Name | Description |
---|---|
cb_id | 요청하는 클러치북 ID |
sort | 정렬 (0: 인기순, 1: 최신순) |
pageNo | 요청하는 페이지 번호 |
pageCount | 한 페이지당 로딩할 댓글 갯수 |
Name | Description |
---|---|
clutches | 로딩된 클러치 목록(리스트) |
clutches.clutchId | 이 클러치의 ID |
clutches.cb_id | 클러치북의 ID |
clutches.cb_name | 클러치북 이름 |
clutches.userId | 클러치를 올린 유저의 ID |
clutches.userName | 클러치를 올린 유저의 이름 |
clutches.userPhoto | 클러치를 올린 유저의 프로필 사진 |
clutches.content_type | 클러치 종류 |
clutches.content_pictures | (옵션, 사진만) 사진들 (공백으로 구분) |
clutches.content_link | (옵션, 동영상 및 링크만) 링크 URL |
clutches.content_link_thumb | (옵션, 동영상 및 링크만) 링크 썸네일 이미지 |
GET /user/fa4230491alf/cb/1853ffba sort=0 pageNo=0 pageCount=50 >>>>>>>>>> { status: { code: 200, message: "성공" }, clutches: [ { clutchId: "fa4230491alf", cb_id: "fa4230491alf", cb_name: "걸스데이", userId: "fa4230491alf", userName: "신광수", userPhoto: "(no pic)", content_type: 0, content_pictures: "pic1id pic2id" }, { clutchId: "fa4230491alf", cb_id: "fa4230491alf", cb_name: "걸스데이", userId: "fa4230491alf", userName: "이호연" userPhoto: "(no pic)", content_type: 1, content_link: "http://thedeblur.com:1129/videos/1934205" content_link_thumb: "(no pic)" } ] }
========