A Journey of Discovery: Using Server-Driven UI to Power the Wattpad Homepage

Muhammad Osama
May 22, 2020 · 5 min read

The homepage serves as Wattpad’s primary means of enabling our users to passively discover new content or information. In early 2019, we set out to completely redevelop the technology powering our home experiences across backend, mobile, and web in order to enable a system that allowed for rapid iteration and experimentation. This series of blog posts aims to describe some of the core philosophies that drove this project, with this post focusing on the concept of “Server-Driven UI”.

Motivation

The existing APIs powering home followed a traditional setup in which they solely provided the groups of information (“modules”) that were to be presented to users. It was then up to the clients to interpret this response and determine how it was to be presented to users. Though we were not frequently changing the UIs on home, this setup meant that we were still required to individually make changes on each frontend platform in order to ship new modules. As a result, we were collectively tied to the constraints of each client, making it such that the slowest client (in terms of iteration speed) was able to determine the timelines of any new changes being rolled out on home.

Enter Server-Driven UI

As an example, given the following UI:

While a traditional API response may provide data on each of the stories being shown:

A server-driven UI approach would abstract away the data in favour of only providing information on the UI-component that needs to be shown:

By introducing server-driven UI to the home experience, we solved several challenges:

  • Enabling consistency of experience across clients as each would now be guaranteed to be displaying the same information.
  • Reducing duplication of work as most iterations on home would only require server changes.
  • Removing dependencies on App and Play Store release timelines.

API Design

Mapping Sections to UI Components on Android

Our Android stack uses a combination of the Paging Library, Moshi, and Epoxy to build the home experience. We currently don’t make use of React Native in our app due primarily to performance and app size considerations.

For example, given the following section:

…we would create a SmallNavigationSection data object on the client along with an appropriate UI component:

Once a PageKeyedDataSource has fetched the API response from the server, the type to class mapping included in HomeSection#UiType is used by our parsing code to inflate the appropriate class using Moshi:

We then make use of an Epoxy Controller to map section objects to the relevant UI views:

Putting this all together gives us a flow that takes the API response and maps it to the UI that is shown to users. Note that all information regarding the placement and inflation of UI was provided by the server, with the client serving solely as a rendering layer.

Challenges and Next Steps

However, this approach is not without its own set of challenges:

  • The server now has to keep track of the specific clients and app versions that support any particular UI component in order to adapt the information appropriately to any given user.
  • Providing all information via the server required us to move towards a world in which our Go microservices have to start keeping track of languages and localizing responses appropriately.

We’re working on solutions to these and other challenges as we continue to build our server-driven UI approach, and hope to share them with you in the future.

Have you used server-driven UI? We’d love to hear how you approached the specific challenges that may have been brought up in your use cases!

I’d like to recognize the entire Content Discovery team at Wattpad for their work on redeveloping our home experience, as well as Laura Kelly’s talk at Droidcon for being a source of inspiration throughout our journey towards server-driven UI.

techatwattpad

Building at Wattpad: Engineering, Product, Design