개발자

목록 CRUD API를 어떻게 짜야할지 고민입니다.

2023년 08월 07일조회 2,529

유저와 1:N 관계인 테이블의 레코드 목록을 생성하고 수정하는 API를 개발하려 합니다. 커리어리의 "관심 분야 설정" 기능을 예로 들어보겠습니다. 다음 두 가지 방법을 생각중입니다. 1. 개별 CRUD: RESTful한 방법이라고 생각이 들고, 구현도 어렵지 않습니다. 다만 많은 업데이트가 있을 때 그만큼의 요청을 서버로 날려야 합니다. (ex: 관심 분야를 BE, FE, AI 에서 UI, 마케팅, 기획으로 바꾸려면 최소 PUT request를 3번 날려야 합니다. 초기 설정 시에도 POST request가 3번 날아갑니다.) 2. POST나 PUT으로 리스트를 제공하면 서버에서 덮어쓰기: 단일 endpoint, 단일 request로 생성, 수정, 삭제가 가능합니다. 다만 서버에서 DB 변경 시 덮어쓰기 방법이 고민됩니다. 가장 간단한 방법은 유저 ID가 FK로 걸려 있는 모든 레코드 삭제 후 리스트에 있는 레코드를 전부 추가하는 방법일텐데, 이런 SQL 로직을 써도 될지 잘 모르겠습니다. 어떤 방법으로 API를 개발하는 게 좋을까요? 혹시 더 좋은 방법이 있다면 알려주시면 감사하겠습니다~

이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.

답변 2

인기 답변

삭제된 사용자님의 프로필 사진

삭제된 사용자

2023년 08월 08일

1번 방법과 2번 방법 중 어떤 방법이 더 좋은지, 2번 방법의 데이터 관리가 괜찮은지에 대한 질문인 것 같아요 먼저 1번 방법의 경우 목록이 많아지면 많아질 수록 많은 요청과 자원이 필요하게됩니다 예시의 경우만 하더라도 6번의 요청과 6번의 응답, 3번의 삭제 쿼리, 3번의 추가 쿼리, 3번의 저장을 하게됩니다 2번의 경우 1번의 요청과 1번의 응답, 1 ~ 3번의 삭제 쿼리, 1 ~ 3번의 추가 쿼리, 1번의 저장을 하게 되겠죠 제 기준에서 좋은 방법은 효율적이면서 더 적게 요청하면서 더 적은 쿼리를 하는것이라 2번 방법이 좋아보입니다 2번 방법의 데이터 처리 방법은 괜찮아보입니다 보통 RESTful 하다고 이야기하는 것은 HTTP Method와 상태 중심적인 어떠한 스타일을 얘기하는 것이라 개별적으로 처리하는 것과 리스트로 처리하는 것은 RESTful한 API와는 관계가 없어보입니다 저는 관심 목록 같은 기능을 구현할 때 이렇게 구현했습니다 GET - 유저의 관심 목록을 데이터베이스에서 조회하고 반환합니다 POST - 요청된 목록을 중복이 아니라면 (중복 검사는 쿼리로 했습니다)데이터베이스에 추가하고 저장합니다 PUT - 유저의 관심 목록을 모두 삭제한 뒤 요청의 목록을 추가하고 저장합니다 PATCH - 요청된 목록과 유저의 관심목록을 비교해 삭제되어야할 항목과 추가되어야할 항목을 구분하고 데이터베이스에서 삭제 후 추가하고 저장합니다 DELETE - 요청된 목록을 모두 데이터베이스에서 삭제하고 저장합니다 최초 등록이나 이후 추가만을 원할 때는 POST로 배열을 담아 요청했습니다 질문에서처럼 일부만 변경하는 경우 변경 후의 결과를 배열에 담아 PATCH로 요청했습니다 전체 변경하려는 경우 변경 후의 결과를 배열에 담아 PUT으로 요청했습니다 태그같은 것이 아닌 식별이 가능한 개별 삭제의 경우에는 HTTP DELETE /:id 같은 end point를 활용합니다 저는 PATCH도 사용하긴 하는데 데이터의 내용을 수정하는게 아니라서 상황에따라 PUT으로 모두 삭제 후 추가하는 것이 더 빠를지는 모르겠습니다 그치만 아무래도 데이터가 커지면 PATCH가 효율적입니다

노우준님의 프로필 사진

노우준

작성자

연세대학교 응용통계학과, 컴퓨터과학과2023년 08월 08일

자세한 설명 감사합니다! 또 여러 메소드를 통해 항상 목록을 덮어쓰는 게 아니라 추가, 삭제 등 클라이언트가 여러 선택을 할 수 있게끔 하는 방법이 인상 깊습니다. 도움이 많이 되었습니다 👍

인기 답변

밴쿠버리안님의 프로필 사진

안녕하세요 저는 api 백엔드 시니어구요. 커리어리 관심분야 설정은 상대적으로 굉장히 단순한 로직이므로 api 한번호출로 하는게 좋겠습니다. 서비스 레이어에서 DB로부터 가져온 내용과 페이로드 내용을 비교해서 없는 항목만 업데이트 하시면 됩니다. 전체지우고 추가해도 되고, 바뀐내용만 추가 삭제하셔도 됩니다. ORM이면 신경 안쓰셔도 되구요. 그리고 본론 1, 2번 질문에 대해서 제너럴한 답변을 드리자면, 1번 경우는 당장은 크게 문제가 되지않으나, 여러 리퀘스트의 타이밍이슈, 개별리퀘스트의 실패성공 여부, 일부 실패시, 롤백되지않는 성공한 리퀘스트에 대한 데이터가 무결성 여부, 그리고 QA및 디버깅등 유지보수가 관건이라고 생각되고요. 2번 경우에는 upsert라고 해서, insert 나 update를 service layer에서 결정 해주면 되구요. insert update를 페이로드 데이터로 결정하거나 디비내용보고 확인하는 등 여러방법이 있는데 개인적으로 전자를 선호하구요. 업데이트 대신 delete insert하는것도 나쁜방법은 아니며 상황에 따라 쓰일수 있겠으나 auto generated 되는 컬럼이 있다면 그에따른 사이드 이펙이나 하위호환성문제는 없는지도 고려해야 겠습니다.

노우준님의 프로필 사진

노우준

작성자

연세대학교 응용통계학과, 컴퓨터과학과2023년 08월 31일

자세한 설명 감사드립니다! upsert로 구현하는 방법이 가장 좋아보여서 그렇게 해보도록 하겠습니다.

고범준님의 프로필 사진

고범준

세명대학교 컴퓨터학부2023년 08월 31일

감사합니다! 혹시 2번의 경우에서 페이로드 데이터로 결정을 한다는게 프론트에서 값이 변경됐을때 플래그를 주고 그걸 기반으로 결정을 하는걸까요?

밴쿠버리안님의 프로필 사진

밴쿠버리안

캐나다 Senior Software Engineer2023년 08월 31일

@고범준 페이로드에 특정값의 유무로 결정해 버리시면 됩니다. 보통 id가 존재하면 업데이트, 아니면 insert로 합니다. 말씀하신 플래그로 하셔도 됩니다.

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

목록으로

지금 가입하면 모든 질문의 답변을 볼 수 있어요!