Developer decisions in Stateful Functions application

Tymur Yarosh
DevOops World … and the Universe
3 min readNov 2, 2021

The weirdest thing in programming is that the more approaches engineers invent, the fewer options we can use. During the early days of our industry, programmers could do every damn thing they wanted to make the product work. Then, Edsger Wybe Dijkstra discovered structured programming paradigm. He showed that replacing goto statements with if/then/else and do/while/until constructs leads to better code. The adoption of the structured programming approach removed the option of using goto statements in our code. The same thing with other paradigms, architecture patterns, frameworks, and so on. Every new approach suggests doing A over B.

Before we dig deeper into Stateful Functions and decisions SF application developer makes, let me guide you through the design and implementation of Stateful Function application.

A or B — we always have to choose what approaches to use and avoid in our software. Rich domain models or anemic? Can the function be anemic? Sure. Should the function be anemic? We’ll see. What approach to choose when combining functions into namespaces? Stateful Functions provides two types of SDK: Embedded and Remote. You can use both. But how to choose the proper one for your particular case? Last week, I presented at Flink Forward Global, and I want to highlight a few things from my talk. I hope you will find them helpful when making your decisions.

How to design a function

Account and Transaction functions

Stateful Function has id, state, and behavior. The same attributes have a business entity. If you design a banking application that manipulates account balance, you probably think about two entities: Account and Transaction. The Account can carry a balance and provide an interface to change it, while the Transaction is the reason to change. Account balance is a state; changing balance is a behavior. This is a way we used to develop business entities in OOP. Stateful Functions are extremely good at implementing those entities because of exactly-once state consistency, data close to the function, and no concurrent modification issues.

How to design a namespace

Packaging principles

Two bold packaging principles are beneficial when designing namespaces:

Common Closure Principle — components that have the same reason to change belong to the same namespace.

Common Reuse Principle — components that tend to be reused together belong to the same namespace.

The opposite is also true.

Remote vs Embedded SDK

Since the early days of Stateful Functions, embedded functions have been the only option for Java developers. But today, we can implement both Embedded and Remote functions. Here is a comparison to help you make a decision.

Comparison of remote and embedded functions

Code examples

To demonstrate how to implement these suggestions, I’ve published the example project to Github. Here you can check the Account and Transaction namespaces with their functions inside. Also, remote module configuration is available in the statefun directory.

I want to thank the organizers of Flink Forward for their support and the opportunity to talk to a broad audience. It was a fantastic experience!

--

--