Best practices

Cloudstate is ideally suited to the creation of small, isolated services, sometimes called Microservices. There are some patterns of Microservice architecture that are well-suited for Cloudstate services. For a more detailed discussion, see The Reactive Principles new tab or the Reactive Architecture courses from Lightbend Academy.

Service design principles

As you build and deploy services, these design principles will be useful:

Defining service boundaries

We recommend use of Domain Driven Design (DDD) to determine the best way to divide responsibility and state between services. Lightbend provides a free course on Domain Driven Designnew tab. See the information on determining service boundaries in the "Decomposing the Domain" chapter, "Identifying Bounded Contexts" section.

Isolation

Each service you create should emphasise isolation--the service should be able to stand alone.

One entity per service

It is best to have each service deal with a single entity. If you have more than one entity, it is not possible for Cloudstate to route the data events optimally across the system.

Update from events, not commands

Your service must not update its in-memory state directly as a result of a command. The handling of a command, if it results in changes being required to state, should emit events to Cloudstate. These events will then be received, at which point the in-memory state can and should be changed in response.

State from events

When you need to read state in your service, ask yourself what events should I be listening to. When you need to write state, ask yourself what events should I be emitting. See Event sourcing for more information.

Message schema migration

A design issue you should plan for is the evolution of your message schemas. Commands and events have a definition, which amounts to a schema, and this schema often needs to evolve over time. Fields get added, fields get removed, the meaning of fields may change.

How do you handle this over time as your system grows and evolves?

Protocol Buffers offers a number of facilities that support evolution and migration across versions, but it is something that must be planned and handled carefully, so new versions of services don’t have problems reading older event journals that they can’t understand.