시도하게 된 배경

우리 회사는 고객사별로 커스터마이징된 소프트웨어를 제공한다.
우리 팀은 신규로 신설된 웹 플랫폼팀으로 신규 프로젝트들을 많이 착수했다.
그러다보니, 제한된 인원으로 여러 프로젝트들을 관리하고 유지/보수하는 데에 있어 많은 에너지가 들었다.
지속적으로, 고객사에서 추가적인 요구사항이 들어오고 있는 상태이다.
이를 극복하기 위한 방안을 고민해보았다.
한꺼번에 해당 프로젝트를 리팩토링하는 것은 신규 업무 / 기존 업무 등에 의해 시간적 배분이 어려웠다.
그래서 우선적으로 프로젝트 내 우선순위가 높은 필요로 하는 페이지 내에 한 탭을 작업하기로 한다.
해당 작업이 잘 완료된다면, 다른 페이지들도 충분히 좋은 레퍼런스로 적용가능할 것이라 보았다.
또한, 기존 담당자가 없어지더라도 훨씬 관리가 수월하고 유지보수가 원활할 것이라 판단되었다.

요구 사항 분석

현재 고객사에서 기존에 지정되어 있던 메뉴들과 옵션들을 직접 설정할 수 있도록,
그리고 추가 / 삭제 가능하도록 요청했다.
최대한 자유롭게 변경 가능하게 하기 위해선 base가 단단하게 설계된 약속이 필요했다.
해당 웹 소프트웨어의 경우, Client(Front-end) -> Server(Back-end) -> Embedded Server(임베디드) 순으로 연결되어 있다.
임베디드 측에선 하드웨어의 제한 때문에 (정확한 원인은 알 수 없음) 정수, 실수, 최댓값, 최솟값 등의 타입 등 여러가지 제한을 Client 단에서 처리해주길 원했다.
그래서 지속적인 커뮤니케이션을 통해 JSON 형태로 UI를 그리기 위한 Key값들을 정의하고,
해당 JSON들을 매핑시켜 UI를 만들어내는 방식으로 구현했다.
한 카드 내에 해당하는 UI를 그려내고 데이터를 함께 받아오는 방식으로 진행했다.

image.png

크게는 4가지 유형으로 Switch, Text, Number, Select 의 Input 형태를 받아오는걸로 합의를 보았다.

image.png

위 이미지는 명세의 일부(다른 부분은 Private...)인데, 디테일한 특징들은 설명하기 어렵겠지만
전문 용어가 label에 많이 들어가기에 설명을 위한 tooltip, uiType에 따른 Input 출력 등 해당 Key들의 값을 통해 UI를 만들어냈다. 갯수는 무한으로 늘어날 수 있도록 매핑해서 반응형으로 UI를 구현하기로 했다.

Component 구성

image.png

클라이언트 코드는 위와 같이 구성하였고, 모듈화되어 추후 확장가능하도록 설계하였다.

UI Result

image.png

위 UI는 샘플로 그려낸 것이고, 8개의 약속된 JSON이 들어올 경우, 위와 같이 나타나게 된다. 각 액션과 상태는 모두 문제없이 동작하는 것을 확인했다.

개선 사항

1. 중복될 수 있는 groupName 처리

그룹 내의 각 인풋의 아이디가 고유하지 않고 같은 경우가 있을 수 있다고 했다.
그건 임베디드 모듈에서 컨트롤하기 어렵다고 클라이언트에서 처리를 해달라고 했기에,
간단하게 각 인풋의 id를 groupName과 묶어 유니크한 id를 만들어주었다.
해당 유니크 아이디를 바라보고 request, response할 수 있도록 수정했다.

2. C++ 하드웨어 모듈 데이터 최적화

클라이언트(프론트) - 로컬 서버(백엔드) - 임베디드 모듈(C++) 방식으로 통신이 되고 있다. 임베디드 모듈은 하드웨어라 최대한 성능을 최적화하는 것이 중요했다. 그래서 데이터를 받을 때는 모든 데이터를 받지만, 다시 보내줄 때에는 변경된 값들만 보내주는 게 효율적이었다. 해당 사항을 개선하기 위해 그룹 내의 각 인풋의 아이디를 잡아 필터링해서 변경된 값만 보내줄 수있도록 수정했다. 또 한 가지로, 하드웨어 상 정밀한 제어가 필요해 소숫점까지 숫자를 받아야 하는 옵션들이 많았다. 들어오는 valueType이 “String”, “Boolean” 그리고 일반 “Number”가 아닌 정수(Integer)와 부동소숫점 데이터(Float)를 구별해서 받아주어야 했다. 그래서 valueType을 체크하는 함수를 중간에 추가해주고 서버로 보내주기 전 해당 valueType을 체크하는 옵션을 추가했다.