Article Image Service Composition

Service Composition

I’ve recently gone through and separated a (admittedly small) system into several different services, so wanted discuss the different boundaries I’ve defined, the reasoning behind them, and the trade offs.

What are we Building?

This is a webapp similar to Pinterest.  Users will create Galleries of images with tags, comments, and ratings for the images.

Some points like authentication seem rather clear-cut, so I’ll omit those for brevity.  Assume there is already a “User Service” and a “Gallery Service”.  This below batch of features required a little more thought:

  • Command: follow / unfollow a Gallery
  • Query: galleries a user follows
  • Query: recommended Galleries for a specific User (based on other Galleries they follow)
  • Query: most recently updated Galleries (for app home-page)
  • Query: most popular galleries (also for app home-page)
  • Query: how many followers a Gallery has

Which services would you break these into?  What boundaries would you draw?  And most importantly, why?

Seems more an art than a science.  One extreme, the classic “big ball of mud” would throw everything into a single service.  This would usually be the fastest to build and most performant, but will cause problems when trying to scale and maintain.  The opposite extreme would separate each “feature” into an independently deploy-able service, where you might end up with so many services it becomes unwieldy, not to mention the excessive data duplication and inter-service communication.

The three main approaches I’ve seen are:

  • Group by what is presented together in UI
  • Group by the data
  • Group by the “features”.

With other important things to consider:

  • What happens when one service goes down?
  • Will they need to scale differently?
  • Can they accept different amounts of latency?
  • What are the inter-service dependencies (direct or indirect)
  • If a developer is tracking down a bug, how will they know which service it belongs to?

In the end I’ve broken it into these services:

  • Follows-Service
    • Follow / unfollow a Gallery
    • Source of truth for list of Gallery’s followers.
    • Query Galleries a User follows
  • Gallery Service
    • Cached and stale-tolerant Gallery-followers-count
  • Gallery-Stats Service
    • Most popular galleries
    • Most recently updated Galleries
  • Recommendation Service
    • User-specific Gallery recommendations

I’m prioritizing clarity of the system (ie, a Service has smaller, single responsibility, and generally does what it’s called) and de-coupled scaling. So many other services depend on follow/unfollow, that it made most sense for it to stand on its own.  I also anticipate it to have the heaviest write-frequency, so being able to scale it independently is critical as well.

Would you have separated things differently?  Were there other factors you would have considered?  Please leave a comment to help me (and anyone reading) compose better systems!

ScottPlusPlus

Working to upgrade our democracy by making voting more awesome (ex: STAR Voting). Reach out if you want to chat about saving the world.

Leave a Reply

Your email address will not be published. Required fields are marked *