안녕하세요, GS리테일의 모바일 FO 팀에서 근무하고 있는 Alan 입니다.
저는 모바일 FO 팀에서 우리동네GS 의 Front-end 와 BFF 개발을 담당하고 있습니다.
우리동네GS 에서는 API 요청/응답 처리를 편리하게 할 수 있도록 BFF 를 사용하고 있습니다.
BFF 개발 과정에서 발생했던 이슈들과 이를 해결하기위한 과정들을 이야기 해보려 합니다.
BFF 도입 배경
우리동네GS 통합 이전
우리동네GS 출시 전, GS 리테일에서는 총 5개의 서비스를 운영중이었습니다.
- 나만의 냉장고
- GS 수퍼마켓
- THE POP
- 우리동네 딜리버리
- 와인25플러스
먼저 오픈한 3개의 앱(나만의 냉장고, GS 수퍼마켓, THE POP) 은 각자의 API 서버 를 두고, 필요한 정보를 요청하는 형태로 개발 되었습니다. 후에 오픈한 와인25플러스와 우리동네 딜리버리는 필요에 따라 기 구축된 API 서버에 기능을 추가하는 방식으로 개발이 진행되었습니다.
우리동네GS 통합
새로운 서비스로 통합 작업을 시작하기 전, 개발팀은 서비스의 전체 구조에 대해 논의를 진행했습니다.
각 앱의 대표 서비스 (원플러스콘, 사전예약, 구독서비스 등...) 를 하나의 앱 화면에서 제공하는 방향으로 UI 가 설계되었지만,
위의 구조를 우리동네GS의 UI 에 적용할 경우, 아래와 같은 이유로 서비스 운영에 걸림돌이 될 것이라는 결론에 도달했습니다.
- Front-end 에서 유지/관리해야 할 정보의 양이 증가합니다.
→ Front-end 에서 API 의 정보 (URL, Query string, Request/Response body) 를 모두 저장해두고 있어야 합니다. - 빠른 응답시간을 위해, 여러개의 Request 를 병렬로 처리해야 합니다.
→ Front-end 에서 UI 관련 작업 이외에 해야 할 일들이 증가합니다. - 이후 연동해야 할 서비스가 추가/수정 될 때 마다, 앱 업데이트가 필요하다.
→ Query string 이나 Request body 등에 작은 변경사항이 있어도, 앱 업데이트가 필요합니다. - 위 1~3의 이유로, QC 부담이 증가합니다.
→ 소스코드 변경 시 Side effect 의 체크 범위가 증가합니다.
대표적인 예가 우리동네GS 홈 화면이었습니다.
위와 같은 기능을 구현하기 위해서는 아래와 같은 처리를 APP 에서 해야 합니다.
- APP 에서 모든 API 서버의 주소를 유지/관리
- API 의 Response 를 APP 에서 사용 가능하도록 가공
- 성능 향상을 위해, 각 Request 는 병렬로 처리
이는 시간이 지날수록 Front-end 와 QC 업무 부담을 과중시키는 요인으로 보았습니다.
이 때문에, 복수의 API 서비스에 데이터를 병렬로 요청하고, 각 API 의 응답을 가공해줄 '배달부'가 필요했는데,
이 때, 사용한 방법이 BFF(Back-end For Front-end) 입니다.
BFF(Back-end For Front-end)
배달부 - BFF
BFF 란, Front-end 에서 필요한 정보를 Back-end 에 요청하고,
Back-end 에서 온 Response 들을 Front-end 에서 처리할 수 있도록 해주는 서비스 입니다.
Front-end 와 Back-end 사이에서 Request 를 각 API 에 요청하고, 응답받은 Response 를 Front-end 로 전달해주는 역할을 하는데, 마치 Front-end 와 Back-end 사이에서 배달부와 같은 역할을 합니다.
BFF의 제약사항
위에 이야기했던 것 처럼, BFF 는 배달부 역할을 합니다. BFF 로 인해 발생할 수 있는 복잡성을 최소화 하기 위해, 몇가지 제약사항을 정했습니다.
- 비즈니스 로직 작성을 최소화 할 것.
- Front-end 와 Back-end 의 요구사항 (Request / Response 의 형태)을 최대한 맞출 것.
해결 방법이 나왔으니, 이제 BFF 설계를 해 봅시다~!
BFF 설계
우리동네GS 에서 BFF 에게 주어진 역할은 간단했습니다. 다시 설명하자면,
- Front-end 로 부터 요청을 받아 Back-end 에게 전달한다.
- Back-end 로 부터 응답을 받아 Front-end 에게 전달한다.
- 전달하기 전, 처리가 용이하도록 query / body 를 재가공한다.
입니다.
우리동네GS 개발팀은 BFF 가 할 작업들에 대해 추상화 작업을 진행했습니다.
추상화 - 타입
위에 설명한 유스케이스에 따라, 각 위치에서 BFF 역할을 써보면 아래와 같이 정리됩니다.
BFF 는
- Request 가 입력되면 Request 를 출력한다.
- Response 가 입력되면 Response 를 출력한다.
API 입장에서 바라보는 BFF 는
- Request 를 가져오고(입력)
- Response 를 가져간다.(출력)
Front-end 입장에서 바라보는 BFF 는
- Request 를 가져가고(입력)
- Response 를 가져온다.(출력)
그리고, 위의 Request / Response 들에게 타입명을 부여하는 작업을 진행합니다.
Front-end ↔ BFF
- 요청은 BffRequest
- 응답은 BffResponse
BFF ↔ API
- 요청은 ApiRequest
- 응답은 ApiResponse
타입에 대한 추상화는 완료되었습니다, 다음으로 BFF 에서 하는 동작을 추상화 할 차례 입니다.
추상화 - 동작
타입 추상화가 완료되었으니, 이번엔 BFF 에서 어떤일을 하는지 생각해 볼 시간입니다.
우리동네 GS 서비스에서 API 와 Front-end 의 입장을 다시한번 설명하자면,
Front-end
"BFF 에서 어떤일을 하는지는 관심 없고, BffRequest 를 보낼테니 BffResponse 를 줘~"
API
"BFF 에서 어떤일을 하는지는 관심 없고, ApiRequest 를 보내주면, ApiResponse 를 돌려줄께~"
입니다.
그러면 BFF 해야 할 일은
- BffRequest 가 오면 ApiRequest 로 바꿔서 API 에 전달
- ApiResponse 가 오면 BffResponse 로 바꿔서 Front-end 에 전달
로 정리됩니다.
BFF 가 해야 할 가장 기본적인 동작은 정의되었습니다.
추상화 - Request 조합
기본적인 동작이 정의되었으니, 이번엔 동작을 조합할 차례입니다. BFF 역할에 대해 다시 설명하자면
복수의 API 서비스에 데이터를 요청하고, API 의 응답을 Front-end 에서 처리하기 쉽도록 가공작업을 진행한다.
입니다.
복수의 API 에 데이터를 요청하고, 응답을 가공하기 위해 위에서 정의한 Request 들을 어떻게 조합할 것인지 결정이 필요합니다.
use case 들에 대해 ApiRequest 전달 방식을 분류하면, 크게 두 가지로 나뉩니다.
- ApiRequest 가 순서대로 처리되어야 하는 경우 (순차적 처리)
→ 이전의 ApiResponse 가 다음의 ApiRequest 에 포함이 되어야 하는 경우 - ApiRequest 가 순서에 상관없이 처리가 가능한 경우 (병렬적 처리)
→ ApiResponse 가 다른 ApiRequest 에 영향을 미치지 않음
BFF 에서는 use case 에 따라, ApiRequest 들을 순서대로 처리할지, 병렬로 처리할지 결정하기만 하면 됩니다.
BFF 설계 - 결론
"각 요청 별 Type 을 바꿔주는 모듈을 만든 후, 이들을 순차적 / 병렬적 으로 연결만 해준다."
우리동네GS 개발팀은 추상화 과정을 통해, BFF 가 해야 할 일들을 정의 했습니다.
- BffRequest 를 받아 ApiRequest 로 변환한 후 요청한다.
- ApiRequest 를 요청하는 방식은 use case 에 따라 다르다.
→ 순서대로 처리할 수도 있고, 병렬로 처리할 수도 있다. - ApiResponse 를 받으면 BffResponse 로 변환한 후 응답한다.
BFF 구현 시, 코드로 작성해야 할 사항도 같이 정의됩니다.
- BffRequest 를 ApiRequest 로 바꿔주는 모듈
- ApiRequest 를 순차적으로 처리하는 모듈
- ApiRequest 를 병렬적으로 처리하는 모듈
- ApiResponse 를 BffResponse 로 처리하는 모듈
구현해야 할 코드작업도 정의가 완료 되었습니다. 이제는 구현만 남았습니다.
이황춘 | 디지털서비스본부 > 모바일FO팀
우리동네GS 앱 / BFF 개발 담당
함수형 패러다임과 액터 모델에 관심이 많은 개발자입니다.
참고자료
- Sharma, H., & Bhat, N. (2022). Backend for Frontend in Microservices. International Research Journal of Engineering and Technology, 09(06), 3075–3080. https://www.irjet.net/archives/V9/i6/IRJET-V9I6614.pdf
'APP' 카테고리의 다른 글
Flutter Code Push의 고찰 (7) | 2023.10.11 |
---|---|
엔터프라이즈 MSA 이야기 3탄 – SR 도메인 편 (9) | 2023.08.01 |
Flutter App 실시간 CDN 이미지 변경 상태 적용 방안 (1) | 2023.06.20 |
엔터프라이즈 MSA 이야기 2탄-RateLimit 적용으로 시스템장애 예방하기 (0) | 2023.06.20 |
GS SHOP App의 메모리 확보 (2) | 2023.05.12 |