세상에 나쁜 코드는 없다

[앱프로젝트:동아리방] 개발 노트 4. API 설계 본문

웹개발/백엔드

[앱프로젝트:동아리방] 개발 노트 4. API 설계

Beomseok Seo 2023. 2. 8. 17:34

API 설계

내가 맡은 부분은 프로젝트의 메인 로직 부분인 팀과 관련된 부분이었다. 팀에서 요구되는 기능은 아래와 같다.

  • 팀은 2가지 분류로 나뉜다. (공모전 팀, 스터디 팀)
  • 각 팀에 대한 정보를 조회할 수 있어야 한다.
    • 공모전 팀은 특정 공모전에 해당하는 팀들을 모아 볼 수 있어야 한다.
    • 스터디 팀은 스터디의 세부 분야 (어학, 자격증, 프로그래밍 등)에 따라 모아볼 수 있어야 한다.
    • 팀 조회시 최신순과 마감순으로 정렬하여 확인할 수 있어야 한다.
  • 팀을 생성 및 수정할 수 있어야 한다.
  • 사용자는 원하는 팀에 신청할 수 있다.
  • 팀의 개설자는 신청한 팀원의 정보를 확인하고 팀원으로 승인하거나 거부할 수 있다.
  • 사용자는 마이페이지에서 자신이 참여하고 있는 팀의 정보를 확인할 수 있다.

위 기능을 수행하기 위해 구성된 API 는 다음과 같다.

팀 관련 API

[GET] /teams

조건에 따른 팀의 정보를 반환한다.

[POST] /teams

주어진 정보에 따라 팀을 생성한다.

[GET] /teams/{teamId}

개별 팀에 대한 정보를 반환한다.

[PATCH] /teams/{teamId}

주어진 정보에 따라 팀 정보를 수정한다.

팀 조회에 있어서 최초의 기획은 [GET] /teams 는 팀을 모아보는 화면에서 사용되는 API 였기 때문에 팀에 세세한 정보를 다 반환할 필요가 없다고 판단하여 요약된 (팀 모아보기 화면에서 필요한 정보만) 반환하도록 했고, 해당 화면에서 특정 팀을 클릭할 때는 자세한 정보를 모두 보여줄 필요가 있었기 때문에 [GET] /teams/{teamId} 에서는 대부분의 정보를 다 반환하도록 했다. 이렇게 개발하는 것이 프론트 입장에서도 각각의 화면을 렌더링할때 불필요한 정보를 받아오지 않아 혼란이 적을 뿐 더러 서버의 부하도 적을 것이라고 판단했다.

하지만 API가 특정 화면이 렌더링하는 부분에 대해 의존하게 되는 것 같은 점이 조금 우려가 되었다. 이 부분은 장단점이 있어보이지만 일단 전자를 채택하기로 했다.

팀원 관련 API

팀원은 User와 Team 간의 다대다 구조를 갖는 리소스이다. 이 경우 서브 리소스를 사용하여 API를 설계하기로 했다.

고민을 했던 점은 다음과 같다.

팀원 리소스에 대하여 GET 요청을 받는것은 그 의미가 비교적 분명하게 드러났다고 생각을 한다.

[GET] /teams/{teamId}/users

팀 ID에 해당하는 사용자의 목록을 조회한다.

[GET] /users/{userId}/teams

유저 ID에 해당하는 팀의 목록을 조회한다.

그러나 팀원에 관한 다른 기능들은 더욱 복잡한 요구를 한다.

  • 유저의 팀 참가 신청
  • 팀 개설자의 다른 유저의 팀 참가 요청에 대한 승인 및 거부
  • 유저의 팀 참가 신청 상태 조회

이 API들을 설계할때에 확실한 기준이 있어야 추후에 혼동이 없을 것 같아, 리소스의 변화를 기준으로 하여 작성하기로 하였다.

[GET] /teams/{teamId}/users/{userId}

유저의 팀에 대한 신청 상태를 조회한다. 미신청, 신청됨, 승인됨, 거부됨 등이 있다.

[POST] /teams/{teamId}/users/{userId}

유저의 팀에 대한 신청을 처리한다. DB에 TeamMember에 레코드가 추가된다.

[PATCH] /teams/{teamId}/users/{userId}

유저의 팀에 대한 신청을 승인 및 거부한다. DB의 TeamMember의 해당하는 레코드의 상태가 변경된다.

이러한 식으로 HTTP method 를 구분하여 API를 설계했는데, API 시그니처만 봤을 때는 이게 어떤 행동을 하는지 의미를 파악하기가 어려워 보일것 같아서 걱정이 된다.

Enumeration 관련 API

팀 생성을 할 때나 조회를 할 때 사용하는 조건들이 프론트 측에서 하드코딩 되는 것을 막기 위해 이 요소들의 리스트를 전달해주는 API가 필요해 보였다. 이러한 목적으로 만들어진 API를 /enums/… 로 모아서 클라이언트측에 제공하고자 했다.

[GET] /enums/common/keywords

서비스에서 제공되는 ‘키워드’를 조회한다.

[GET] /enums/common/meeting-systems

회의 방식 (대면,온라인,병행) 을 조회한다.

[GET] /enums/studies/areas

스터디 분야를 조회한다.

[GET] /enums/contests/areas

공모전 분야를 조회한다.

등등…

API 문서 작성 방식

API 문서를 프론트 측에 제공하는 방식으로는 Swagger를 사용하고자 했는데, (내가 알기로는) Swagger가 Java 코드를 읽어서 문서를 만드는 방식이라 Controller 에 코드가 작성되어 있어야만 프론트 측이 확인할 수 있었다. 따라서 어느정도 완성된 API 문서를 프론트 측에 제공하기에는 시간이 걸릴 것 같아서, 일단 Google Sheet 로 간단하게 만든 API 문서를 먼저 제공하고, 이후 Swagger로 제공하기 위해 빠르게 컨트롤러 부분을 작성하는것을 목표로 하였다.


Uploaded by N2T