# 에어비앤비 사례로 보는 Server-driven UI 🛏
애플과 MS 등 OS 플랫폼의 확고했던 경계가 조금씩 섞이는 추세입니다. 여러 플랫폼을 지원하는 서비스도 이전에는 확고한 네이티브 영역이 있었던 반면, 여러 플랫폼으로 변환되는 하나의 소스로 통합하려는 움직임이 있습니다. 최근 급부상한 Flutter처럼요. 그래도 Flutter와 같은 서비스는 데이터를 제공하는 서버의 역할과 데이터를 UI와 함께 표현하는 클라이언트의 전통적인 역할을 그래도 잇고 있습니다. 여기 한발 더 나아가 UI까지 서버가 제공하는 개발 구조가 있습니다.
Client가 아닌 서버가 UI를 제공한다는 개념은 인터넷의 탄생부터 함께한 구조와 달라, 상상이 안 갈수도 있는데요. 대부분의 서비스가 멀티 플랫폼인 요즘, 이 Server-driven 개발 구조를 구축한다면 많은 이익을 볼 수 있을 것 같습니다. 에어비앤비 개발팀이 Server-driven UI를 적용한 경험을 공유해 주었습니다. 이 개념을 알고 의도한 게 아니더라도, 신규 프로덕트나 개편하는 서비스라면 '언제나 진화하는 소프트웨어'의 관점에서 자연스럽게 Server-driven UI를 지향하고 있다는 생각이 듭니다.
<Server-driven UI의 탄생>
• 전통적으로 데이터는 백엔드가, UI는 각각의 클라이언트가 제공했다. 이 구조에서 클라이언트는 서버에게 데이터를 요구하고, 받은 데이터를 적절히 변환하여 UI로 표현하였다.
• 이 방식은 세가지 이슈가 있었다. 첫째, 특정 UI에서 수정사항이 있을 경우 클라이언트가 데이터를 변환하고 렌더링을 수정하는 일은 빠르게 복잡해질 수 있다. 둘째, 클라이언트 별로 플랫폼에 종속적인 부분이 있어 클라이언트 버전이 쉽게 나뉘게 된다. 셋째, 모바일 서비스 자체가 버전이 있기 때문에, 사용자가 앱을 업데이트하기 전까지 기다려야 한다.
• 이러한 이슈로 부터 나온 구조가 Server-driven UI이다. Server-driven UI는 데이터와 함께 UI를 클라이언트에 전달한다. 클라이언트는 보내진 정보대로 그리기만 하면 된다.
<에어비엔비의 SDUI, The Ghost Platform>
• 에어비엔비는 SDUI 구조를 가지는 The Ghost Platform이 있습니다. Ghost는 에어비엔비의 두가지 중심인 Guset와 Host 기능의 합성어입니다.
• The Ghost Platform는 웹, iOS, 안드로이드에 동시다발적이고 빠르고 안전하게 신규기능을 추가할 수 있습니다. The Ghost Platform는 각 클라이언트 언어를 지원하는 플랫폼별 프레임워크를 제공하기도 하여, 클라이언트 개발자가 쉽게 server-driven 피처를 만들 수 있습니다.
• The Ghost Platform의 핵심 기능은 generic한 섹션, 레이아웃, 액션, 그리고 호환이 필요한 여러 백단의 라이브러리를 공유할 수 있다는 것입니다. 이는 여러 팀의 복잡한 비즈니스 로직을 한곳에서 관리할 수 있다는 의미입니다.
<표준화된 스키마>
• The Ghost Platform의 기본 뼈대는 표준화된 데이터모델입니다. 데이터모델이 표준화 되어있으면, 어떤 클라이언트는 UI를 그릴 수 있습니다. 데이터모델 표준화를 위해, 에어비엔비 팀은 백엔드 서비스의 데이터 레이어에서 사용하던 통합 데이터 매쉬 Viaduct를 레버리지로 사용했습니다.
• 모든 클라이언트에서 단일의 GraphQL 스키마를 사용하기로 하였고, 이는 SDUI의 확장성을 쉽게 높여주었습니다. 에어비엔는 모든 플랫폼에서 response 핸들링과 데이터모델 생성을 동일한 스키마로 합니다.
• 유니버설 스키마는 재사용하는 섹션, 다이나믹 레이아웃, 서브페이지와 액션 그리고 상호작용하는 모든 기능에서 사용할 수 있습니다. 화면의 특수성이 있다면 유니버셜 스키마를 레버리지하여 UI렌더링에 사용할 수 있습니다.
<두가지 메인 UI 컨셉, Sections과 Screens>
• response에는 두가지 메인 UI가 있습니다. Sections는 가장 기본적인 블럭으로, 노출되는 실제 데이터 분류 기준으로 나뉜 독립적인 요소입니다. 번역, 포맷, 로컬라이징도 이미 적용된 UI로 각 클라이언트는 Section Data를 받아 UI로 그리기만 하면 됩니다.
• Screens은 여러 Sections의 레이아웃 정보를 담고 있습니다. 각 Section이 어디에 배치되는 지, 화면은 전체적으로 어떤 구성인지를 알려줍니다. 또한 popover, modal 같은 Sections의 UX 정보와 메타데이터인 로그 정보도 담습니다.
• Sections과 Screens는 Container안에 각각 필요한 정보를 가지는 구조입니다. Sections은 타입과 이미지 같은 소스와 액션을 가지고, Screens은 레이아웃과 네비게이션 정보, 풋터 정보 등을 가집니다. response는 이렇게 잘 구조화된 Sections 스키마와 Screens 스키마를 보내줍니다.
⟪참고⟫
- Flutter, https://flutter.dev/
- Adam Miskiewicz, Taming Service-Oriented Architecture Using A Data-Oriented Service Mes, 2020.11.11. https://medium.com/airbnb-engineering/taming-service-oriented-architecture-using-a-data-oriented-service-mesh-da771a841344