Rails Unfit for Microservices?

This is a relatively informal blog post. Looking more for feedback and response to get a conversation started. The prerequisite to this thread is that you have a fairly good understanding of Microservices. If not at least read the following link:
http://martinfowler.com/articles/microservices.html



About 2 years ago I dropped from Java development and moved on to Ruby and Rails. This was a business decision, and personally, I was excited to challenge myself and help grow as a developer. My blog has been fairly inactive since then.

There are two reasons for my inactivity:
  1. Learning a new language requires much time reading, implementing experimenting, and interacting with the community to understand and build great software.
  2. The Ruby community is already awesome.
Learning a new language is challenging and time consuming.
I have to admit that Ruby was a fairly big change from Java. With Groovy experience, it wasn't a far stretch but under the covers, it is very different. I still can't get over non declared types on initialization, but a variable can't take on a new type there forward (dynamic yet strong typed). This was bizarre to me. I also missed interfaces, but at the same time loved modules. I have to say that Ruby is the most syntactically beautiful language used in enterprise technology. The style in which you write code in Ruby is completely driven by the community, and what they deem as acceptable in their open source software. This leads me to my next point..

The Ruby community is awesome.
There is no other open source community out there as interactive and cohesive as the Ruby community. I had no reason to blog because, so many great writers and community projects had what I needed, or enforced standards through community driven development. This community is amazing and incredibly adaptable. 

Rails is pretty cool too.
Rails is by far my favorite full stack web framework. It has great docs, tooling, and community support through gems and Rails engines. If a custom write would cost my company X weeks or months to solve, there would almost always be a gem I could use. Rails is lighter then most all full stack Java web frameworks, and all lack the same community support.

The problem with Ruby: It's heavy dependency on Rails.

At the time of this writing, there were near 24000 stars on github for the Rails project. There are also countless gems that support Rails only. If Rails drops, that is a bunch of wasted time and code (which there should be a real need for some time). Obviously we know that Rails is heavily opinionated on how we work within it's framework and also lacks modularity. It's all or nothing. This can be a problem long term, if the architecture of software changes. That brings me to micro services.

A trend towards microservices
Micorservices Architecture is a loosely defined architecture based around the early SOA principles. A web application is a small service that preforms very few or a single task. A call from a client, may be an orchestration of services on the back-end. A service may just receive and persist data. It could proxy requests, mediate between services and clients, translate messages, queue to/from a topic exchange, deliver messages via various transport protocols and more.

Not everyone needs micro services architecture (MSA)
Martin Fowler has articulated in his article the requirements before thinking MSA. I would suggest reading it before continuing. Jeppe Cramon, also has a pessimistic, but realistic look at MSA architecture in his article on the TigerTeam blog. If you still feel MSA fits your needs, and have done the research, you will find Rails has a hard time adapting to this architecture.

Does Rails fail in the Microservice realm?
In MSA, services are not full stack. When you tear down a service to business logic, translation and validations, does it really need Rails? Probably not. At the same time there are parts of Rails that would make our lives easier. As a developer, we don't want to re-implement active record validation (which is modular with active model validations), or the routes API, MVC components and active record of course. The thing is that Rails is convenient in full stack development,  but lacks modularity if needing to break it apart for MSA. It's unfortunate, but a real issue. The same holds for Groovy and Grails. They are already taking an initiative to modularize their stack to prepare for MSA. This is a good step, that I feel the Ruby community should take note of.

Will Ruby fall behind if MSA is adopted?
Absolutely not. Why? Because the community is awesome. There is heavy dependence on Rails in the Ruby community, but there are also libraries that will suite perfectly in MSA. For example, CelluloidRack Server Interface (Rails is built on), and parts of Sidekiq are capable tenants for MSA. Multi-threading in ruby should be sufficient enough, since green threads are smart enough to handle Non-blocking IO. Where this may fall is if you need to thread business logic, that is not dependent on external services. This cannot be truly threaded, but only efficiently threaded (minus JRuby). 

The community will prevail
Luckily for rubiests, they drive the future of Ruby and will ultimately decide if MSA needs to be adopted. My fear as always, is that Ruby could pigeonhole itself into Rails, and not break from the standard. Why? Because it's good enough most of the time. If that is the case, and you want to build an MSA system, then think hardly about how it's designed. 

MSA and Rails
Services would likely be full stack but manage a small subset of the business, and it's models. Those could also be broken down and separated based on various data aggregates. A uniform REST API, will be crucial as well. Where would this simple implementation fall short? The ability to scale multiple services on the same server would be lost. Services would likely talk directly, and have to know each others APIs which would inherently force coupling between services. These are key issues discussed in MSA, and in the Rails world would need the right tooling to resolve. The other option is to claim you do MSA, but really be doing the stuff that makes sense. This approach may be enough for your needs. We can liken it to the hypermedia (HATEOAS) part of the REST spec. Most claim REST support but never adopt hypermedia in their API. This is because the community has decided that REST is good enough without it (most of the time). The same may bode for MSA in the future. That is an unknown (what is good enough).

I'm going back to Java (Mostly) for MSA
Java is already ahead of the curve in MSA with things like spring boot, spring HATEOAS, reactor, and various Netflix contributing libraries, along with Zookeeper for service discovery/registration. There will be support for Rails if a team would like, but they will have to build the tooling to integrate within the system. Part of that is giving up much of the free tools that Rails offers. Our Identity Provider is a Rails application. Since it does not integrate nicely with our MSA, we will have to build a service to mediate calls to it. This overhead is necessary but unwanted. Unfortunately Rails is opinionated and may not be best suited for MSA yet.

Thoughts and responses are welcome.


Comments

Popular posts from this blog

Atmosphere Websockets & Comet with Spring MVC

Microservices Tech Stack with Spring and Vert.X