Skip to content

(협업) API 재설계

Choi Woo Seok edited this page Oct 19, 2023 · 1 revision

기존 문제점

  • API가 너무 화면에 의존적이기 때문에(화면에 필요한 정보만 줌) 만약 기능이 조금 바뀌거나, 화면이 바뀌게 되면, 안드로이드 쪽 코드와 백엔드 쪽 코드가 모두 바뀌게 되는 문제점이 있었다. 이로 인해, 이전 안드 버전을 쓰는 사용자는 앱을 강제 업데이트 해야만 사용할 수 있었다.

개선 방안

  • API를 화면에 의존적이지 않고, 도메인을 받도록 변경한다.

스펙 변경

[GET: 존재하는 Activity 전체 조회]

링크

Response

[{
		"activityType" : "동아리",
		"id" : 4,
		"name" : "인프콘"
		},
		"activityType" : "동아리",
		"id" : 4,
		"name" : "인프콘"
		},
		{
		"activityType" : "동아리",
		"id" : 4,
		"name" : "인프콘"
}]

[POST: 새로운 Activity 등록]

Request

{
  "activityIds" : [ 4, 5, 6 ]
}

Response

[{
		"activityType" : "동아리",
		"id" : 4,
		"name" : "인프콘"
		},
		"activityType" : "동아리",
		"id" : 4,
		"name" : "인프콘"
		},
		{
		"activityType" : "동아리",
		"id" : 4,
		"name" : "인프콘"
}

‼️ [POST: 사용자의 Activity 등록 API]

링크[POST: 새로운 Activity 추가] 링크 가 같은 API인데 이름만 다릅니다!

[DELETE: 사용자의 Activity 삭제 API]

링크

Request

{
  "activityIds" : [ 4, 5, 6 ]
}

Response

[{
		"activityType" : "동아리",
		"id" : 4,
		"name" : "인프콘"
		},
		"activityType" : "동아리",
		"id" : 4,
		"name" : "인프콘"
		},
		{
		"activityType" : "동아리",
		"id" : 4,
		"name" : "인프콘"
}

**[GET: 사용자의 Activity 조회]

링크**

Response

[{
		"activityType" : "동아리",
		"id" : 4,
		"name" : "인프콘"
		},
		"activityType" : "동아리",
		"id" : 4,
		"name" : "인프콘"
		},
		{
		"activityType" : "동아리",
		"id" : 4,
		"name" : "인프콘"
}
  • 더 이상 사용되지 않는 API입니다.

Respsone

{
  "id" : 1,
  "name" : "김길동",
  "description" : "안녕하세요, 김길동입니다.",
  "imageUrl" : "https://image",
  "githubUrl" : "https://github.com/amaran-th"
  "activities": [
  {
			"activityType" : "동아리",
			"id" : 4,
			"name" : "인프콘"
	},
			"activityType" : "동아리",
			"id" : 4,
			"name" : "인프콘"
	},
	{
			"activityType" : "동아리",
			"id" : 4,
			"name" : "인프콘"
	}
}

[GET: 사용자의 id를 기반으로 사용자가 작성한 모든 함께해요 요청 조회]

링크

Response

[ {
	  "postId" : 1,
	  "content" : "함께해요~",
	  "updatedAt" : "2023-07-15"
	  "member" : {
			  "id" : 1,
			  "name" : "김길동",
			  "description" : "안녕하세요, 김길동입니다.",
			  "imageUrl" : "https://image",
			  "githubUrl" : "https://github.com/amaran-th"
			  "activities": [
			  {
						"activityType" : "동아리",
						"id" : 4,
						"name" : "인프콘"
				},
						"activityType" : "동아리",
						"id" : 4,
						"name" : "인프콘"
				},
				{
						"activityType" : "동아리",
						"id" : 4,
						"name" : "인프콘"
				}
},
	  "event" : {
			  "id" : 1,
			  "name" : "인프콘 2023",
			  "informationUrl" : "http://infcon.com",
			  "startDate" : "2023:08:15:12:00:00",
			  "endDate" : "2023:08:15:12:00:00",
			  "applyStartDate" : "2023:08:01:12:00:00",
			  "applyEndDate" : "2023:08:15:12:00:00",
			  "location" : "코엑스",
			  "tags" : [ "코틀린", "백엔드", "안드로이드" ],
			  "thumbnailUrl" : "https://www.image.com",
			  "type" : "COMPETITION",
			  "imageUrls" : [ "imageUrl1", "imageUrl2" ],
			  "organization" : "인프런",
			  "paymentType" : "유료",
			  "eventMode" : "온라인"
		}
},
...
]
[{
  "id" : 1, o 
  "name" : "인프콘 2023", o
  "informationUrl" : "http://infcon.com", o
  "startDate" : "2023:08:15:12:00:00", o
  "endDate" : "2023:08:15:12:00:00", o
  "applyStartDate" : "2023:08:01:12:00:00", o
  "applyEndDate" : "2023:08:15:12:00:00", o
  "location" : "코엑스", o
  "tags" : [ "코틀린", "백엔드", "안드로이드" ], o
  "thumbnailUrl" : "https://www.image.com", o
  "type" : "COMPETITION", o
  "imageUrls" : [ "imageUrl1", "imageUrl2" ],
  "organization" : "인프런",
  "paymentType" : "유료", o
  "eventMode" : "온라인" o
},
{
  "id" : 1, o 
  "name" : "인프콘 2023", o
  "informationUrl" : "http://infcon.com", o
  "startDate" : "2023:08:15:12:00:00", o
  "endDate" : "2023:08:15:12:00:00", o
  "applyStartDate" : "2023:08:01:12:00:00", o
  "applyEndDate" : "2023:08:15:12:00:00", o
  "location" : "코엑스", o
  "tags" : [ "코틀린", "백엔드", "안드로이드" ], o
  "thumbnailUrl" : "https://www.image.com", o
  "type" : "COMPETITION", o
  "imageUrls" : [ "imageUrl1", "imageUrl2" ],
  "organization" : "인프런",
  "paymentType" : "유료", o
  "eventMode" : "온라인" o
},
...
]

Response

[ {
	  "postId" : 1,
	  "content" : "함께해요~",
	  "updatedAt" : "2023-07-15"
	  "member" : {
			  "id" : 1,
			  "name" : "김길동",
			  "description" : "안녕하세요, 김길동입니다.",
			  "imageUrl" : "https://image",
			  "githubUrl" : "https://github.com/amaran-th"
			  "activities": [
			  {
						"activityType" : "동아리",
						"id" : 4,
						"name" : "인프콘"
				},
						"activityType" : "동아리",
						"id" : 4,
						"name" : "인프콘"
				},
				{
						"activityType" : "동아리",
						"id" : 4,
						"name" : "인프콘"
				}
},
	  "eventId" : 1L,
},
...
]

class Member(
    Long id: Long,
    String name,
    String description,
    String profileImageUrl,
    String githubUrl,
    List<Activity> activities,
)
// 복잡해서 클래스로 표현했습니다..ㅠㅠ
Response -> List<Comment>

class Comment(
    Long id: Long,
    String content,
    Member author, // Member는 특정 Member 조회할 때 얻는 Member와 동일합니다!
    LocalDateTime createdAt,
    LocalDateTime updatedAt,
    Comment parentComment?,
    List<Comment> childComments,
    Long feedId,
    Boolean deleted,
)
Response : Comment

class Comment(
    Long id: Long,
    String content,
    Member author, // Member는 특정 Member 조회할 때 얻는 Member와 동일합니다!
    LocalDateTime createdAt,
    LocalDateTime updatedAt,
    Comment parentComment?,
    List<Comment> childComments,
    Long feedId,
    Boolean deleted,
)

[POST : 댓글 및 대댓글 생성]

링크

Request

{
  "content" : "내용",
  "feedId" : 1,
  "parentId" : null
}

Response

 class Comment(
    Long id: Long,
    String content,
    Member author, // Member는 특정 Member 조회할 때 얻는 Member와 동일합니다!
    LocalDateTime createdAt,
    LocalDateTime updatedAt,
    Comment parentComment?,
    List<Comment> childComments,
    Long feedId,
    Boolean deleted,
)

[PATCH : 댓글 수정]

[링크[(https://kerdy.kro.kr/docs/index.html#patch%EB%8C%93%EA%B8%80_%EC%88%98%EC%A0%95)

Request

{
  "content" : "변경된 내용"
}

Response

 class Comment(
    Long id: Long,
    String content,
    Member author, // Member는 특정 Member 조회할 때 얻는 Member와 동일합니다!
    LocalDateTime createdAt,
    LocalDateTime updatedAt,
    Comment parentComment?,
    List<Comment> childComments,
    Long feedId,
    Boolean deleted,
)

[GET : 전체 스크랩 조회]

링크

Response

[{
  "id" : 1, o 
  "name" : "인프콘 2023", o
  "informationUrl" : "http://infcon.com", o
  "startDate" : "2023:08:15:12:00:00", o
  "endDate" : "2023:08:15:12:00:00", o
  "applyStartDate" : "2023:08:01:12:00:00", o
  "applyEndDate" : "2023:08:15:12:00:00", o
  "location" : "코엑스", o
  "tags" : [ "코틀린", "백엔드", "안드로이드" ], o
  "thumbnailUrl" : "https://www.image.com", o
  "type" : "COMPETITION", o
  "imageUrls" : [ "imageUrl1", "imageUrl2" ],
  "organization" : "인프런",
  "paymentType" : "유료", o
  "eventMode" : "온라인" o
},
{
  "id" : 1, o 
  "name" : "인프콘 2023", o
  "informationUrl" : "http://infcon.com", o
  "startDate" : "2023:08:15:12:00:00", o
  "endDate" : "2023:08:15:12:00:00", o
  "applyStartDate" : "2023:08:01:12:00:00", o
  "applyEndDate" : "2023:08:15:12:00:00", o
  "location" : "코엑스", o
  "tags" : [ "코틀린", "백엔드", "안드로이드" ], o
  "thumbnailUrl" : "https://www.image.com", o
  "type" : "COMPETITION", o
  "imageUrls" : [ "imageUrl1", "imageUrl2" ],
  "organization" : "인프런",
  "paymentType" : "유료", o
  "eventMode" : "온라인" o
},
...
]

[GET : Room UUID로 쪽지방 조회]

링크

[GET : 쪽지함 목록 조회]

링크

Response

[ {
  "roomId" : "b067d0ed-9758-45c0-a3a1-2efea9ac6149",
  "interlocutorId" : 1,
  "interlocutorName" : "receiver1",
  "interlocutorProfile" : "imageUrl1",
  "recentlyMessage" : Message
  },
  {
     ...
  },
]

class Message(
    Long id,
    String content,
    Member sender,
    LocalDateTime createdAt,
)

[GET : Room UUID로 쪽지방 조회]

링크

Response

[ {
  "sender" : Member,
  "content" : "내용1",
  "createdAt" : "2023:10:11:08:32:25"
}, 
...
]

class Message(
    Long id,
    String content,
    Member sender,
    LocalDateTime createdAt,
)

[GET: 피드 목록 조회]

링크

Response

{
  "feeds" : [ {
    "id" : 34,
		"eventId" : 1L,
    "title" : "피드1 제목",
    "content" : "피드 내용",
    "writer" : Member,
    "images" : [ "https://image1.url", "https://image2.url" ],
    "comments" : List<Comment> ,
    "createdAt" : "2023:07:13:11:43:11",
    "updatedAt" : "2023:07:13:11:43:11"
  }, {
    "id" : 35,
    "title" : "피드2 제목",
    "content" : "피드 내용",
    "writerId" : 43,
    "images" : [ ],
    "commentCount" : 3,
    "createdAt" : "2023:07:22:23:54:49",
    "updatedAt" : "2023:07:22:23:54:49"
  } ]
} 

class Feed(
    Long id: Long,
    String title: String,
    String content: String,
    Member writer: Member,
    List<Comment> comments,
    List<String> imageUrls,
    LocalDateTime createdAt,
    LocalDateTime updatedAt,
    Long eventId,
)

 class Comment(
    Long id: Long,
    String content,
    Member author, // Member는 특정 Member 조회할 때 얻는 Member와 동일합니다!
    LocalDateTime createdAt,
    LocalDateTime updatedAt,
    Comment parentComment?,
    List<Comment> childComments,
    Long feedId,
    Boolean deleted,
)

data class Member(
    val id: Long,
    val title: String,
    val content: String,
    val writer: Member,
    val comments: List<Comment2>,
    val imageUrls: List<String>?,
    val createdAt: LocalDateTime,
    val updatedAt: LocalDateTime,
    val event: Event,
)

Response

[{
    Feed,
    Feed,
    ...
}]

class Feed(
    Long id: Long,
    String title: String,
    String content: String,
    Member writer: Member,
    List<Comment> comments,
    List<String> imageUrls,
    LocalDateTime createdAt,
    LocalDateTime updatedAt,
    Event event,
)

**[GET: 피드 상세 조회]

링크**

response : Feed

class Feed(
    Long id: Long,
    String title: String,
    String content: String,
    Member writer: Member,
    List<Comment> comments,
    List<String> imageUrls,
    LocalDateTime createdAt,
    LocalDateTime updatedAt,
    Event event,
)
Clone this wiki locally