다음 절차는 내가 실무(MSA, graphql 환경)를 통해 터득한 스키마, API 설계 방법이다.
뭘 하든 간에 이게 가장 우선이다. 처음에는 도메인 이해가 부족하기 때문에 스키마나 API 설계도 어렵다. 하지만 점차 설계를 하면 할수록 도메인에 대한 이해도 올라간다. 도메인에 대한 이해가 올라가면 점차 설계에 쓰이는 시간 같은 부하(load)도 줄어든다. 처음부터 잘 하려고 하기보단, 여러 가지 시도를 많이 해보는 게 좋다.
기획서에서 데이터로 사용될 수 있는 것을 추출한다. 글로 써도 무방하고 처음에 완벽하지 않아도 되니 뽑을 수 있는대로 뽑아보자.
뽑은 데이터를 취합하고 데이터의 속성을 파악한다. 저장이 필요하지 않다면 굳이 스키마가 필요 없다. 저장이 필요하다면 영속적인 저장이 필요한지, 임시적인 저장이 필요한지를 체크해야 한다. 그리고 데이터의 업데이트가 너무 잦은 것은 아닌지도 확인해야 한다. 이외의 여러 다른 특성에 따라 적절한 저장소를 선택해야 한다.
일대다, 다대다 등 관계를 찾아내고 정규화를 진행해야 한다.
중요한 데이터라면, 삭제를 막고 soft delete를 적용하자.
스키마 설계 역시 처음부터 잘할 수는 없다. 다음 2,3,4 단계를 진행하던 중 다시 이 단계로 돌아와서 진행하는게 정상이다.
graphql은 스키마만 잘 짜놓으면, API를 따로 만들지 않아도 프론트엔드가 graphql을 통해 자유롭게 쿼리하여 코딩할 수 있다. 이를 통해 백엔드의 시간 절약이 가능하다.
하지만, 단순히 스키마만 프론트엔드에게 던져주면, 스키마가 어떻게 잘못되었는지 아니면 어디가 비효율적인지를 알 수가 없다. 기획서 화면을 보고 직접 graphql을 짜봐야 한다. 직접 graphql을 짜다보면, 다음과 같은 상황이 많이 일어난다.
"음? 이 데이터는 다른 스키마에 배치하는 게 낫겠네.", "edge로 펼쳐보니 이 스키마들의 관계가 너무 중첩되어 있네." ,"이 edge에는 connection이 있으면 편하겠네"
관계가 너무 중첩된 graphql 쿼리는 성능 상 좋지 않다고 한다. 따라서 지양해야 한다. (글을 작성한 현 시점에서는 n+1 문제라는 것이 있다는 것만 알고 있다.) 너무 중첩되어있으면, 쿼리를 어느 깊이에선 끊으라고 프론트에게 말할 필요가 있다.
그리고 edge에 where나 orderBy, first 등의 조건이나 페이지네이션이 필요하다면 connection을 적용하자. entgo의 경우엔 graphql relay spec인 relayConnection()을 적용하면 된다. 해당 기능을 사용하면 프론트엔드가 graphql 쿼리할 수 있는 자유도가 훨씬 높아진다.
graphql은 프론트엔드 개발자들에게 스키마를 다 노출시킨다. 그렇기 때문에 스키마 테이블 이름이나 칼럼 이름 같은 네이밍을 매우 신경써야 한다. 누가 봐도 직관적으로 알 수 있어야 한다. 그렇기 때문에 프론트엔드 개발자에게 이 이름이 와닿는지 반드시 물어봐라.
API 파라미터랑 리스폰스 피드백도 받아봐야 한다. 미처 백엔드 개발자가 생각지 못했던 것들이 있을 수 있다. 예를 들어, 프론트엔드에서 해당 파라미터에 굳이 값을 넣어줘야 하는지? 프론트에서 구분하기 쉽게 리스폰스에 enum을 추가해서 줄 수는 없는지? 등 여러가지가 있다.
API의 멱등성 역시 고려해야 한다. 테스트도 해보고.