Mark is a graph advocate and field engineer for Neo Technology, the company behind the Neo4j graph database. As a field engineer, Mark helps customers embrace graph data and Neo4j building sophisticated solutions to challenging data problems. When he's not with customers Mark is a developer on Neo4j and writes his experiences of being a graphista on a popular blog at http://markhneedham.com/blog. He tweets at @markhneedham. Mark is a DZone MVB and is not an employee of DZone and has posted 527 posts at DZone. You can read more from them at their website. View Full User Profile

Micro Services: A Simple Example

04.05.2012
| 7607 views |
  • submit to reddit

In our code base we had the concept of a ‘ProductSpeed’ with two different constructors which initialised the object in different ways:

public class ProductSpeed {
  public ProductSpeed(String name) {
    ...
  }
 
  public ProductSpeed(String name, int order)) {
 
  }
}

In the cases where the first constructor was used the order of the product was irrelevant.

When the second constructor was used we did care about it because we wanted to be able sort the products before showing them in a drop down list to the user.

The reason for the discrepancy was that this object was being constructed from data which originated from two different systems and in one the concept of order existed and in the other it didn’t.

What we actually needed was to have two different versions of that object but we probably wouldn’t want to name them ‘ProductSpeedForSystem1′ and ‘ProductSpeedForSystem2′!

In Domain Driven Design terms we actually have the concept of a ‘ProductSpeed’ but in two different bounded contexts which could just mean that they come under different packages if we’re building everything in one (monolithic) application.

However, we could see from looking at the way ‘ProductSpeed’ initialised from the second constructor was being used in the application that it didn’t interact with anything else and so could easily be pulled out into its own mini application or micro service.

We’re actually building an API for other systems to interact with and the initial design of the code described above was:

Api before

We get a product from the product list (which is sorted based on the ordering described!) and then post a request which includes the product amongst other things.

After we’d pulled out a micro service it looked like this:

Api after

The choice of product is actually a step that you do before you make your request to the main API whereas we’d initially coupled them into the same deployable.

These are the advantages I see from what we’ve done:

  • We can now easily change the underlying data source of the products micro service if we want to since it now has its own schema which we could switch out if necessary.
  • It takes about 5 minutes to populate all the products and we run the script to repopulate the main DB quite frequently. Now products can be loaded separately.
  • Our code is now much simplified!

And some disadvantages:

  • We now have to deploy two jars instead of one so our deployment has become a bit more complicated.

    My colleague James Lewis points out that we’re effectively pushing the complexity from the application into the infrastructure when we design systems with lots of mini applications doing one thing.

  • Overall I think we have more code since there are some similarities between the objects in both contexts and we’ve now got two versions of each object since they’re deployed separately. My experience is that sharing domain code generally leads to suffering so we’re not doing that.

 

Published at DZone with permission of Mark Needham, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)