실무로 터득한 스키마, API 설계 방법 (MSA +graphql 환경)

dasd412·2024년 12월 10일
0

실무 문제 해결

목록 보기
11/17

다음 절차는 내가 실무(MSA, graphql 환경)를 통해 터득한 스키마, API 설계 방법이다.

0. 비즈니스 도메인 이해

뭘 하든 간에 이게 가장 우선이다. 처음에는 도메인 이해가 부족하기 때문에 스키마나 API 설계도 어렵다. 하지만 점차 설계를 하면 할수록 도메인에 대한 이해도 올라간다. 도메인에 대한 이해가 올라가면 점차 설계에 쓰이는 시간 같은 부하(load)도 줄어든다. 처음부터 잘 하려고 하기보단, 여러 가지 시도를 많이 해보는 게 좋다.

1.스키마 설계

  1. 기획서에서 데이터로 사용될 수 있는 것을 추출한다. 글로 써도 무방하고 처음에 완벽하지 않아도 되니 뽑을 수 있는대로 뽑아보자.

  2. 뽑은 데이터를 취합하고 데이터의 속성을 파악한다. 저장이 필요하지 않다면 굳이 스키마가 필요 없다. 저장이 필요하다면 영속적인 저장이 필요한지, 임시적인 저장이 필요한지를 체크해야 한다. 그리고 데이터의 업데이트가 너무 잦은 것은 아닌지도 확인해야 한다. 이외의 여러 다른 특성에 따라 적절한 저장소를 선택해야 한다.

  3. 일대다, 다대다 등 관계를 찾아내고 정규화를 진행해야 한다.

  4. 중요한 데이터라면, 삭제를 막고 soft delete를 적용하자.

  5. 스키마 설계 역시 처음부터 잘할 수는 없다. 다음 2,3,4 단계를 진행하던 중 다시 이 단계로 돌아와서 진행하는게 정상이다.

2. graphql 쿼리로 짜보기

graphql은 스키마만 잘 짜놓으면, API를 따로 만들지 않아도 프론트엔드가 graphql을 통해 자유롭게 쿼리하여 코딩할 수 있다. 이를 통해 백엔드의 시간 절약이 가능하다.
하지만, 단순히 스키마만 프론트엔드에게 던져주면, 스키마가 어떻게 잘못되었는지 아니면 어디가 비효율적인지를 알 수가 없다. 기획서 화면을 보고 직접 graphql을 짜봐야 한다. 직접 graphql을 짜다보면, 다음과 같은 상황이 많이 일어난다.

"음? 이 데이터는 다른 스키마에 배치하는 게 낫겠네.", "edge로 펼쳐보니 이 스키마들의 관계가 너무 중첩되어 있네." ,"이 edge에는 connection이 있으면 편하겠네" 

관계가 너무 중첩된 graphql 쿼리는 성능 상 좋지 않다고 한다. 따라서 지양해야 한다. (글을 작성한 현 시점에서는 n+1 문제라는 것이 있다는 것만 알고 있다.) 너무 중첩되어있으면, 쿼리를 어느 깊이에선 끊으라고 프론트에게 말할 필요가 있다.

그리고 edge에 where나 orderBy, first 등의 조건이나 페이지네이션이 필요하다면 connection을 적용하자. entgo의 경우엔 graphql relay spec인 relayConnection()을 적용하면 된다. 해당 기능을 사용하면 프론트엔드가 graphql 쿼리할 수 있는 자유도가 훨씬 높아진다.

3. MSA 고려하기

  1. 여러 서버가 있는 MSA의 경우, 데이터가 각 서버에서만 접근이 가능하다. 그런데 graphql은 edge로 연관된 데이터를 특정 서버에서 불러온다. 그래서 MSA+graphql 조합의 경우, 연관된 데이터가 다른 서버에 있을 경우 edge로 불러오기 곤란하다. (이건 아직 연구가 더 필요하다. edge 리졸버 커스텀해서 grpc로 다른 서버 데이터를 불러올 수는 없을까?)
  2. 어쩔 수 없는 중복 데이터는 감안해야 한다. 다른 서버에서 영속화할 필요한 데이터라면, 그 서버에도 어쩔 수 없이 그 데이터를 넣을 수 밖에 없다. 예를 들면, 대부분의 서버 데이터에서 사용되는 userId 같은 칼럼이 있다.

4. API 설계

  1. graphql은 프론트엔드 개발자들에게 스키마를 다 노출시킨다. 그렇기 때문에 스키마 테이블 이름이나 칼럼 이름 같은 네이밍을 매우 신경써야 한다. 누가 봐도 직관적으로 알 수 있어야 한다. 그렇기 때문에 프론트엔드 개발자에게 이 이름이 와닿는지 반드시 물어봐라.

  2. API 파라미터랑 리스폰스 피드백도 받아봐야 한다. 미처 백엔드 개발자가 생각지 못했던 것들이 있을 수 있다. 예를 들어, 프론트엔드에서 해당 파라미터에 굳이 값을 넣어줘야 하는지? 프론트에서 구분하기 쉽게 리스폰스에 enum을 추가해서 줄 수는 없는지? 등 여러가지가 있다.

  3. API의 멱등성 역시 고려해야 한다. 테스트도 해보고.

profile
시스템 아키텍쳐 설계에 관심이 많은 백엔드 개발자입니다. (Go/Python/MSA/graphql/Spring)

0개의 댓글