How to avoid service-to-service calls for plain data

Ürgo Ringo
Wise Engineering
Published in
2 min readJan 17, 2020

--

There are two kinds of dependencies between services: data dependency and behavior dependency. We have a data dependency when we need to find out what is the address of customer X. We have a behaviour dependency when we need to ask if customer Y is eligible for our customer loyalty program.

Autonomy

In both cases using asynchronous communication enables building more autonomous services. Just like it is desirable to build organisation out of autonomous units it is also valuable to build our software system out of autonomous components. Autonomy for services means higher availability, better response time and potentially also faster iteration speed.

Of course there are also downsides. The main one is increased complexity. In some cases asynchronous communication can also make it harder to meet very strict requirements on data freshness.

Event based data replication

One solution to get rid of synchronous calls for data is replicating that data.

Whenever new customer registers herself our “customer-registration” service fires off a “Customer Registered” event. Our “ordering” service listens to these events and stores the data that it finds interesting in its own database.

There are couple of points to keep in mind:

  • we should replicate only the data that we actually need. No point in copying over whole Customer data if we just need the address
  • we should treat replicated data as something we can throw away at any time. This way we will be able to re-run the replication from scratch whenever there are changes in the data schema subset that we care about. Of course this only works if we have the entire history of “Customer Registered” events available somewhere. This is where durable message brokers like Apache Kafka come handy.

Caching in database

One typical solution that is used for making synchronous communication cheaper and more resilient is caching. If the data that we are interested in is immutable then we can cache it forever. Simplest solution for that is using our database that we anyway use for storing “our own” data.

This solution is not fully asynchronous as the first time we need something new we will hit another service. However, it can still help increase service autonomy especially when the same data is needed frequently.

Some sources on the same topic:

Data on the Outside versus Data on the Inside by Pat Helland

Command Query Responsbility Segregation by Chris Richardson

P.S. Interested to join us? We’re hiring. Check out our open Engineering roles.

--

--

Ürgo Ringo
Wise Engineering

In software engineering for 20+ years. Worked as IC/tech lead at Wise. Currently tech lead at Inbank. Interests: product engineering and org culture.