Dynamic Content Strategy

Miguel T
Dynamic Content
Published in
3 min readMar 10, 2023

Dynamic content consists of building entire modules and screens on-the-fly, without having to define static resources to describe the UI, including behaviors, like handling UI events, validating errors, performing navigation and transitions.

This the second article in a series — see https://medium.com/dynamic-content for a complete list.

All the metadata related on how a module, flow, screen, or a specific UI element (aka widget) could be defined:

  • Locally using a static data-model
  • Locally using a persistence layer
  • Or, remotely through API services

At the end, all these three strategies are exactly the same:

  • Data Models define the structures for all layers.
  • Modules could potentially define instances of this Data Model which provides all what is required to Content-Services. All the UI definition is considered as hard-coded.
  • Persistence layer (e.g. using Room Database) could store all the information using the same Data Model structures. Note that this could be used to implement a caching mechanism; offline support; or just store all metadata rather than hard-coding Data-Model instances.
  • Remote Services could define the response payloads using the same Data Model. Obviously, the correct strategy should be caching all the information.

In this way, all the architectural components are consistent across all layers and defining services is easy, scalable, maintainable, and testable.

Data Models, Persistence, and Remote Services vs. Content Services

This is not something new. In the old days imperative UI programming made this somewhat difficult (XML layouts, view-bindings), but the tools and technologies available today make things much easier and fun to work with.

I will focus on Android Jetpack Compose, but the same principles apply to iOS SwiftUI, since both UI-toolkits follow the declarative programming paradigm.

A basic example: Dynamic Surveys

I had to work on a project where different surveys could be delivered to users at any time. Such surveys consisted of 2, 3, 4, “n” different questionnaires, and each one could have several possible answers: single-choice (radio-button), multiple-choice (check-boxes), or even free-text.

There are pros and cons for a static approach:

Advantages

  • Each survey can have its own UX design.
  • Each questionnaire can be customized, organizing answers using a better visual design.

Disadvantages

  • Implies that new surveys will require new mobile-app releases.
  • Longer development times since each questionnaire has to be manually crafted.

To support business requirements, a dynamic approach was taken, where all surveys were provided from an API-request, defining a proper JSON structure that defines the survey itself, its questionnaires, and related answers:

Advantages:

  • No new mobile-app releases were required — all surveys can be defined on the back-end services
  • Shorter development times, since abstractions and generics are defined once

Disadvantage:

  • Overall design lacks customizations per survey / questionnaire / answers

This basic architecture was built in less than 1 month, and it allowed to define any survey, provided the JSON payload complied with the specifications → the “contract”. Answers were saved on a back-end service using a standard format.

In summary, a dynamic approach solved several challenges:

  • How and when to deliver surveys to users
  • How the organization builds new surveys without having to force users to install a new release
  • Decrease time-to-market: development, deployment
  • Coordinate and orchestrate all publishing activities (e.g. specific date and time)

Of course, this “survey solution” only addressed one specific use-case: delivering surveys.

This implies that data-models, mobile components, and API services were all designed around a single conceptual context, forcing to reinvent the wheel for new use-cases.

Can we do better? Absolutely yes!

Dynamic Content Objectives

  • Define a framework to build modules / screens on-the-fly, without having to rely on local hard-coded resources (static layouts, labels)
  • Enforce Separation of Concerns and Single Source of Truth principles:
    - Render UI;
    - Handle UI events (triggered by UI or business-logic);
    - Handle errors;
    - Decouple local / remote requests and responses (repositories);
    - Perform transitions / navigation
  • Streamline all “content” through a unified architecture, totally agnostic from source:
    - Local: offline, cache;
    - Remote services
  • Define a unified Data Model to accommodate all requirements.
  • Outline the “contract” (http-methods, JSON specifications) between clients and remote services to simplify API requests and responses.
  • Define comprehensive policies and mechanisms for widgets that can be managed per release, allowing to add more features incrementally.

Next: Dynamic Content Architecture — coming some time this year…?¯\_(ツ)_/¯

--

--