
Hexagonal Architecture Guidelines For Rails - bestie
http://theaudaciouscodeexperiment.com/blog/2014/03/17/hexagonal-architecture-guidelines-for-rails/
======
jhuckestein
At that point, I wonder what the benefit of using rails is? Rails shines most
when you do things as intended.

Even though I wouldn't have designed rails the way it is (remote forms and
.js.erb views anyone?), it works really well for a large class of
applications.

Of course you may eventually hit a wall, but that happens when software
outgrows it's original requirements. That doesn't mean you have to build a
system for millions of concurrent users from day one. Especially not, when
you're making accounting software or a crm or some other run-off-the-mill
webapp.

In my experience, rails "improvements" are often suggested, when a developer
is faced with a large mudball of a rails application that doesn't do things
according to convention. This can quickly happen, because rails is deceptively
easy to learn. Many developers I know (myself included), started writing a
serious app in Rails, without learning a lot about it. Heck, if you're a rails
developer and honest with yourself, you probably didn't even read all of the
rails guides. In addition to that, I recommend reading a book such as "The
Rails Way" front to cover, joining the mailing list, following the core team's
blogs and potentially even going through the code. I also DON'T recommend
taking your patterns from random blog posts or stack overflow. Rails is very
well documented and you can generally find what you need in the docs.

As infuriatingly dismissive as his tone sometimes is, I've actually found it
best to follow dhh's advice. Not only because I generally agree with it, but
also because it's likely to be the best supported design in future rails
versions.

~~~
sanderjd
There are a few ways to answer the (definitely relevant) question of "if
you're doing things this way, what does rails give you?" In some cases, the
answer is "nothing", and people really just want sinatra if they really like
ruby, or one of the many lighter-weight libraries that other languages have.
In some cases, the answer is "actionpack is still really good at what it does,
even if it's just used as an HTTP adapter". In some cases, the answer is
"activerecord is a really nice ORM". Etc. But I think in most cases, it's
because there are just lots of libraries written for rails, and using sinatra
or padrino (last I looked) tends to result in re-writing some things that you
would otherwise get for free. Although sometimes in order to use those
libraries you need to be doing things "the rails way" anyway.

------
patio11
This feels like it would be the sort of architectural decision which would be
well-served by saying "Here is the app motivating this stunning architectural
purity. You will note that this app both exists and was more complicated than
the 5 Minute Build-A-Blog demo."

Otherwise it's "Rails Project Day 1: Scratch-build a stripped-down ORM. Day
59: That might have been a bit more involved than I expected."

~~~
grey-area
My thoughts exactly. On reading:

 _Controllers actions are allowed a single line of code_

I wonder, why do these controllers exist at all?

    
    
        def show
          app_of_things.show_thing(rails_adapter)
        end
    

Is code like this really useful code? It looks like it was written by a very
short perl script. Why is he using rails at all at this point, rather than
ditching the framework and using a simpler router which talks directly to his
app endpoints? What does this controller add aside from a level of indirection
which will never be useful?

The lack of an example with code running in production makes it very hard to
judge where all this is leading or why you would want to do this.

~~~
hawleyal
Exactly. If they are only one line, why not just have the "app code" handle
the routing as well?

~~~
sanderjd
Well, to separate concerns. ActionController does what it's good at (routing
and rendering), and your application does what it's good at (business logic).
One tangible benefit of separating concerns in this way is that it makes it
possible to use the application itself as a module behind different adapters.
So you can put it behind a raw tcp api, or a 0mq bus, or a command line front-
end, etc., without needing to change anything but the adapters.

It is very reasonable to question whether this is really all that useful or
whether doing it from the start is a premature optimization, but it isn't
pointless.

~~~
matdes
I hear this often but when the frack do you ever interact with a raw tcp api
or a 0mq bus that's existentially the same application as your web app??

~~~
sanderjd
Well, it's interesting. My example is partly contrived and partly not
contrived. I worked on a big application where the web front end was very much
the tip of the iceberg. We had the Rails monolith problems that you frequently
hear decried. One thing we at least thought we would really like to do was
move to an architecture with a bunch of little services talking to each other.
We thought about having them talk to each other over tcp or 0mq, and we
thought it would have been really nice if it were easy to take our existing
application logic and put tcp or 0mq adapters on top of it. I keep saying "we
thought", because we never actually did any of that, which may have been the
case either because our application logic was so tied up with Rails that it
was impractical to pull it apart (as some of us thought), or because it's a
silly idea to begin with.

We did have a good deal of success pulling out libraries though, and
separating concerns helps with that too. (So maybe I chose the wrong argument
to make in my comment before.)

------
danso
It's worth posting DHH's recent interjection into the architecture debate...

[https://news.ycombinator.com/item?id=7335211](https://news.ycombinator.com/item?id=7335211)

tl;dr show some actual working implementation of this paradigm that
exemplifies its benefits over standard Rails

> _Anyway, the invitation stands. Present any piece of real code and we can
> ping pong on it. I enjoy talking about specifics and improving real code. I
> detest "oh that was just a poor example, but the general principle is..."
> kind of debates. If you can't produce a good example, you don't have a
> general principle._

~~~
lnanek2
Yeah, this original post doesn't have sample at the end, heh.

------
RyanZAG
Slowly but surely re-implementing enterprise java in rails...

~~~
adamors
Are you really this afraid of software architecture, that anything that goes
beyond simple MVC is enterprise java?

~~~
RyanZAG
Oh, no I have no problem with enterprise Java - it was merely an observation.
Enterprise Java exists because it works, after all. I just find it interesting
that most software projects will eventually come to the same conclusions
regardless of their original source.

~~~
adamors
I'm not talking about enterprise Java. Why do you equate something more
complex than an MVC pattern to enterprise Java immediately?

------
lnanek2
> Where’s the sample app? > In the works :)

Considering he says people should write their own data mapper, it doesn't
surprise me he is so far behind everyone else he can't even turn out a sample.
You can spend many years writing that alone.

~~~
bestie
Unfortunately they have all been closed source thus far.

The problem with writing _good_ code samples is that it requires a lot of time
and thought. This was very much an MVP blog post and appears demand for the
sample app / code snippets is very real so I will do my best to get something
together.

Isn't more fun to spend all your time arguing on HN though? :)

------
al2o3cr
"Where’s the sample app? In the works."

ARE YOU GETTING ENOUGH OXYGEN, architecture astronauts?

~~~
programminggeek
This is a troll, but holy moly did it make me laugh. Well played.

------
matthewmacleod
Why would you do this?

If you're operating at the level where you need this level of indirection,
then you should be looking at SOA anyway. Rails is not an appropriate
platform, regardless of how much architecture you add to it.

If you're not operating there, then you are introducing complexity for no
reason, and failing to take advantage of the features that Rails offers.

~~~
bestie
Having the indirection there allows you to take the Rails features you want
with your boundary clearly defining which ones you depend on.

You could start with Rails, get ActiveRecord querying, migrations and template
rendering for free and then maybe swap it out for Sinatra and the Sequel gem
(I have actually done this).

Knowing your where your dependencies and technical debts are is very
empowering.

~~~
binarysoul
What does hexagonal mean?

~~~
dcuthbertson
It's a reference to Alistair Cockburn's "Ports and Adapters" pattern, also
called "Hexagonal Architecture".[1] The only reason I ever heard of it is that
it was mentioned in the book "Growing Object-Oriented Software, Guided by
Tests", by Steve Freeman and Nat Pryce (a good book in my opinion).

[1]
[http://alistair.cockburn.us/Hexagonal+architecture](http://alistair.cockburn.us/Hexagonal+architecture)

------
pothibo
The problem with this is that he's building an API on top of something he
doesn't understand. There's no way you can look at this and think it's a good
idea if you have any understanding of how rails works.

When I first read this post, I thought the guy was trolling, seriously.

~~~
thealmightyis
this comment is trolling.

------
mattgreenrocks
Web devs _hate_ him for suggesting that programming technique is important!

No, really, perhaps it is worth giving this a try, if only as a means of
deliberate practice? You _don 't_ get better at programming by plugging in
HN's coolest, most fashionable framework, you get better at it by shipping,
maintaining, and learning to feel the impact of design decisions.

Don't complain you have too much to do, this is building foundational skills
that are language agnostic and will outlive Ruby on Rails. Isn't that way more
important than pulling up Twitter several times today?

~~~
bestie
Webby Rails types do often get very aggressive towards this kind of thinking.
The point you made about this out-living Rails is a very good one. I'd be
coding like this in any language with any framework, Ruby just makes writing
SOLID code easy.

~~~
mattgreenrocks
You can't rely on industry to teach you what you need to know. They'll put you
on endless treadmills learning hackneyed DSLs fueled by hype cycles. Fact is,
Rails is almost entirely composed of patterns from PoEAA, along with DHH's
excellent taste. At some point, you need to read and apply those patterns
yourself to really understand them.

Actually, now that I think about it, you're almost much better off self-
teaching once you get to a certain competency level.

------
carsonreinke
"My advice is to write your own data mapper", noooooooooooo

~~~
flevours
I'd reword data as in "create a clear boundary between your models and the
ORM/ODM you use", which easily translates into defining class methods on the
model which use the underlying ORM/ODM of choice.

~~~
bestie
I think this is a really good point, there is a huge difference between
trivial data mapping and what an ORM does.

Wait while I make this edit ....

------
programminggeek
Obvious Architecture
([http://obvious.retromocha.com/](http://obvious.retromocha.com/)) was heavily
inspired by Hexagonal Architecture and even has a working example app:
[https://github.com/RetroMocha/obvious_status/](https://github.com/RetroMocha/obvious_status/)

For the record, with this kind of architecture, you can take the same codebase
and use it for a web api, standard rails app, sinatra anything, desktop app,
mobile app, or command line app. All using mysql, sqlite, postgres, mongodb,
json files, or just about anything else you want for persistence. And your
tests should all run in less than a second. It's pretty sweet from a purely
technical standpoint. Obvious Status has done that with ruby, but I could see
the same thing being done in Java, C#, or even C++.

I'm not sure why all the rails people are blogging about this kind of
architecture seemingly all at once, but it's not new. It's pretty much where
you end up when your standard MVC codebase gets out of hand on a reasonably
complex project. Uncle Bob spoke over 2 years ago at Ruby Midwest about this
and has blogged about it since then. Obvious came out last January and there
were a few people talking about it since then, but not many.

The real struggle with this kind of structure is that it goes against the
standard Rails patterns and ecosystem. DHH doesn't like it and frankly he's
right. It goes against the whole spirit of Rails. It doesn't fit in with
Rails. Sidenote, DHH originally called it the worst code he's ever seen
attached to Rails, so it's got that going for it.

If you go down the path of clean architecture (in any of its forms), you are
going to have to convince your team of Rails devs to stop using Rails as they
know it. Most Ruby or Rails devs don't want or see the need for this kind of
structure. That is okay. We had to build a lot of things to make building
Obvious apps in Ruby more awesome, but it's an uphill battle. Other languages
give you things like interfaces and method parameter type checking as part of
the language and will even check them at compile time.

Clean Architecture is great, but I think it's going to lead developers away
from Ruby and Rails, at least for the core API portion of their app. I really
don't know what language most developers will land on, but it will probably
have a compiler, it will probably support functional programming and
immutability, it might support OOP, and it will probably be on the JVM. That's
just my guess.

------
styluss
"Any problem in computer science can be solved with another level of
indirection."

~~~
userbinator
...including the lack of people buying faster hardware. ;)

------
dragonwriter
This, to be evaluated, desperately needs more realistic examples, as well as
much better discussion of how the rules relate to the principles of Hexagonal
architecture, and what benefit they provide in that context.

As it is, I can, with some effort, find some justification for some of the
rules in the context of Hexagonal architecture, but as presented its not
immediately clear even what part of Hexagonal architecture the various
elements are relating to.

Perhaps most importantly, it needs to clarify what the application itself and
the "rails adapter" look like here.

------
reedlaw
I feel much of the negative reaction to posts like these fails to grasp the
main idea. My take is that you can use other architectural patterns than MVC
and still benefit from Rails. In fact, you can use patterns that complement
MVC. There is no conflict. Why ignore the history of design patterns and try
to squeeze everything into an MVC-shaped box?

~~~
dragonwriter
> I feel much of the negative reaction to posts like these fails to grasp the
> main idea.

I feel much of _my_ negative reaction to this post and those like it -- and I
am familiar with hexagon/ports-and-adapters architecture -- is failure to
clearly present a main idea, or even to connect the dictates in the post to
the subject in the headline.

> My take is that you can use other architectural patterns than MVC and still
> benefit from Rails.

Certainly, the article seems to be trying to use Rails MVC structure to force
the design of the web-facing adapter in a hexagonal architecture into an MVC
design, what it really fails to do is justify this as a good thing to do
(either in general for building an application, or starting from the
assumption that we should use a hexagonal architecture, or starting from the
assumption that we should use Rails.)

------
lewispollard
Off topic, but how did you come up with the name for the blog? I ask because
there's an awesome record label in my city called the audacious art
experiment... wonder if they're related

~~~
bestie
It is no co-incidence :)

Ben Lane, the founder of The Audacious Art Experiment was one of my closest
friends growing up, we were also in a band together.

~~~
lewispollard
Amazing! I'll make sure to follow your blog :)

------
jlebrech
why not abandon controllers at this point and route directly to show_thing?

~~~
bestie
Route directly how? Write my own HTTP layer? It's so easy to take advantage of
Rails' routing and view rendering.

~~~
grey-area
_Route directly how?_

Well, instead of fighting rails, you could just use the lower level stuff it
is based on which does the bits you want:

Routing - [https://github.com/rack/rack](https://github.com/rack/rack)

Templates - [http://www.ruby-
doc.org/stdlib-2.1.1/libdoc/erb/rdoc/ERB.htm...](http://www.ruby-
doc.org/stdlib-2.1.1/libdoc/erb/rdoc/ERB.html)

Rails adds quite a lot of overhead and complexity, not to mention memory
usage, so if you're going to bypass most of it, it might be better to start
with something more bare-bones?

~~~
thealmightyis
I agree with that, bringing rails in is like bringing a chainsaw to cut a twig
sometimes...

The point here is not to look at the devise/router serving http but the
porting of the data & business logic to an adaptable, multi-purposed api that
is not tied down to the infrastructure in any way.

I've used this approach within a Sinatra driven app, CTO said i need to use
Rails now for some other thing, a few hours to make the switch, not rewrite
the whole thing.

