IMHOs on the API

Martin Povolny mpovolny at redhat.com
Thu Jan 17 10:22:50 UTC 2013


On Wed, Jan 16, 2013 at 04:59:06PM -0500, Matt Wagner wrote:
> On Wed, Jan 16, 2013 at 03:09:13PM +0100, Martin Povolny wrote:
> 

<SNIP>

> > iii) the API structure need not copy the internal structure of the
> > project (being it the models or the controllers)
> > 
> > Actually the API should hide the implementation details as much as
> > possible and it should be structured in a way that is logical from the
> > consumer point of view.
> > 
> > iv) from the above it's obvious that having the API in the same
> > controllers that serve the WUI might not always be the best way to do
> > not only in terms of spaghetti popularity.
> 
> This is where I start to disagree a bit.
> 
> The API doesn't need to expose all the nitty-gritty implementation
> details we have, but having the same controllers and methods service
> both the UI and the API is a common Rails pattern and usually results in
> cleaner, DRYer code. The actions should be doing the same thing
> regardless of whether the consumer is a web browser or an API client,
> with the only difference being whether we respond with HTML or XML/JSON.
> 
> For a long time, we ended up with separate controllers dealing with
> images for the API and the UI. It turned into a big mess, with a lot of
> duplication. Worse than duplicate code, we started getting divergent
> duplicate code, where someone would fix something in the UI controller
> but not the API, and things just turned into a hard-to-maintain mess.
> 
> Of course, like you wrote in your email, this is all just IMHO.
> 

On the turning into mess, one more IMHO, that I wrote in the thread on
delayed-launch: There's a layer missing. If you have domain logic in the
controllers than you have spaghetti and the situation you wrote about.

Then you move your domain logic into the model and again you have a mess
-- the "Large Model" problem.

Now comes my IMHO: You have to limit the responsibility of the models.

In (my IMHO) perfect world you would limit it to the (de)serialisation,
but that's something you never do, it's like the
http://en.wikipedia.org/wiki/Ideal_solution

You refactor the methods that do domain stuff using method objects resulting
into something like the service objects or service layers or explicitly
extend model instances with functionality as the DCI guys suggest.
Just do whatever you call it to separate the different responsibilities
from the model into separate classes.

If you do this then you will have less pasta in the controller, you will
not have duplicated code in case of separate controllers for WUI and API
and you will not find code fragments that propagate flash messages from
the model through controller to the view either ;-)

And as a side bonus, you can write real unit tests for the domain logic
that really run fast because they need not touch the database once the
serialisation responsibility is separated.

Again if you read my IMHOs up to this point, I thank you and you can
even ask me for a beer once you come to Brno.

-- 
Martin Povolny <mpovolny at redhat.com>
tel. +420777714458


More information about the aeolus-devel mailing list