← Back to all posts

Think about RIOTS

September 4, 2024 · 4 min read

RIOTS!!!

What do riots have to do with software engineering? Nothing. But it’s a handy acronym for thinking about system design.

  • R - Retrieval
  • I - Input
  • O - Output
  • T - Transformation
  • S - Storage

The vast majority of software development involves those 5 actions and very little else. If you can break the problem down to those fundamentals, designing and building a solution becomes much easier.

In most apps, you’ll be Retrieving information from a data store. That information becomes Inputs into assorted functions which Transform the data. The Output of those functions is the Input for further functions. Finally, the data is Output either to the screen, a file, or Storage.

This pattern can apply at the class level as well as higher levels. If you follow Uncle Bob’s examples of SOLID programming, you’ll see how the Output of one function in a class becomes the Input for another (Dependency Injection) with each function applying a single Transformation (Single Responsibility).

RIOTS in Microservices

A common microservice architecture pattern is just RIOTS. A microservice stores data in its database (Storage). Debezium watches for Storage events, takes that event as Input, Transforms it based on your rules, and Outputs it to a system like Kafka where another microservice can Retrieve each entry in the Kafka topic and pass it as Input to a function that Transforms the data and Stores it in its own database.

RIOTS in the Real World

Let’s take a look at a solution from (way back) my history:

The problem: we need to be able to upload VERY large (>1GB) files to Azure Cloud Storage as fast as possible.

The solution:

  1. Read the file.
  2. Break it into small chunks.
  3. Store the chunk in a queue to be processed.
  4. Inspect each chunk to see if it has data or should be discarded.
  5. Upload the chunk to the appropriate place if it has data.

Reading the file is Retrieval. Breaking it into chunks takes the stream as Input, transforms part of the stream, and Outputs an object with the chunk of bytes and some metadata. Storing the chunk in the queue is Storage. Processing the chunk Retrieves a chunk from the queue, takes the chunk as Input, and Transforms by determining whether the chunk is empty or has data. If the chunk has data, we Output it by uploading it via Azure’s API.

Each of these steps is simple and single-purpose. And with each step being simple, it’s far easier to build, test, and maintain.

Try It

Next time you’re faced with a design problem, think about RIOTS. Break it down to those fundamentals and see if the solution becomes clearer.