
Why I No Longer Use MVC Frameworks - talles
http://www.infoq.com/articles/no-more-mvc-frameworks
======
lhorie
I feel like this is one of those cases where someone rejects currently
existing tools, but then goes on to throw out the baby with the bath water
when trying to come up with an alternative.

Figure 7
([http://cdn.infoq.com/statics_s2_20160209-0057/resource/artic...](http://cdn.infoq.com/statics_s2_20160209-0057/resource/articles/no-
more-mvc-frameworks/en/resources/fig7.jpg)) looks to me like the sort of MVC
you would do with vanilla PHP or friends back in the day.

In figure 9
([http://cdn.infoq.com/statics_s2_20160209-0057/resource/artic...](http://cdn.infoq.com/statics_s2_20160209-0057/resource/articles/no-
more-mvc-frameworks/en/resources/fig9.jpg)): he handwaves saying that you can
compose things, but nothing in the article suggests that SAM provides better
mechanisms to sync data between client and server. E.g. what if the view is a
table, and the action is deleting an item? Does an update consist of re-
downloading a whole new table worth of data? Would it also do that if I
deleted that same item from some other view? Or does it require 2 http
requests in series (a DELETE followed by a GET)? What would an undo action
look like in terms of HTTP requests and responses? The graphs feel like
they're largely meaningless. Having arrows in a diagram pointing from one word
to another doesn't say anything about the complexities of the system.

~~~
Symbiote
> baby w/ the bath water when trying to come up w/ an … w/

Would you mind writing "with"? It's two extra characters, but it makes the
sentence much more readable. (Words are recognized by shape, especially the
shortest ones.)

~~~
savanaly
It's easier for me to parse "w/", for the record. You're right that words
recognizeable by shape, and "w/" looks really distinct to me.

~~~
mmel
c_ b/ g% h) u; q| z* f< h\ i. f% v< d- o# c" a" t/ m~ y+ t] o& o/ r\ c~ o* p(
j] j^ l& u@ d} o^ m& i)

------
Gratsby
People have a hard time with MVC because frameworks that use the phrase MVC
are always more complex than necessary.

There's a simple set of separations that you need to pay attention to for your
code to be what I like to call "not stupid".

1\. Separate your code from your data. You shouldn't be kicking out HTML with
your code, like this guy does in figure 1. When you combine HTML or any
display information with code that means your designer is your coder and your
coder is your designer. Designers suck at code. Coders suck at design. Keep
that shit separate.

2\. Separate your logic code from your code that changes your data. You
shouldn't be running updates/saves/inserts from 30 different locations in your
code. Define your interface, expect that interface to work. When you need to
shift from Oracle to Redis to RDS, you shouldn't have to refactor 80% of your
application. You refactor your data update code and leave everything else that
works alone.

There you have it. Model, View, Controller. You have a data model that can be
displayed in any number of ways, and you control CRUD on that Model via the
controller. It's not a religion. Just make sure there's a logical separation
within your code so you can delegate as your team and application grows.

Architect things logically and call it whatever you want.

~~~
jdubray
Sorry, but you just don't get the fact that SAM is reactive/functional and
what benefits you can drive from it.

~~~
samstave
I am certainly reactive, but also functional - so thanks for that.

~~~
Gratsby
It took me 2 hours to realize how funny this comment was.

------
johndubchak
I believe another major issue arises in the form of the design of these new
API's are not designed using the historical knowledge that got us here.

It seems to me at least that every 10 years or so a new group of fresh grads
enter the workforce and by sheer will (and all nighters) recreate different
forms of the same solutions to familiar problems.

Meanwhile, the previous designers and implementors seem to fade (who knows
where they end up?) and the normal evolution we should be seeing in our API's,
frameworks, and collective knowledge simply inches (is that too generous?)
along.

We are giving different names to original ideas. For example, I have read
(sorry, I can't find the links) recently where others have published on
interesting new design patterns only to find out they are essentially renamed
versions of the original GoF patterns.

The same challenges exist and we are seeing someone else's take on the
solution and it feels too familiar because they look at what's out there and
provide only a marginal variation on a theme.

I believe this partly explains this "been there, done that" that we're seeing
these days.

~~~
mtkd
Anyone around over 20 years or more will likely agree.

It's not a bad thing in my view. Watching an inexperienced and enthusiastic
team lurch forward with some new hotness, often different angles on old
problems, is one of the things that keeps me interested.

That pioneering community mature and start recognising the similarity of their
deeper issues with more classical computation problems. Then they start to
investigate earlier thinking and solutions - or engaging older developers with
wider knowledge.

But they almost always add something in the early stages as they were not
prejudiced by legacy solutions.

Rails was a good example of this - it massively changed a lot of thinking in
good ways. Many people I met in the early days of Rails went on to need
outputs from earlier generations - niche languages, classical data structures,
lexers, low level debuggers etc. - the very things they thought they were
disrupting.

Older developers are not immune to this - I've sketched out some complicated
(to me) data requirement on a whiteboard, with some loose thinking on how we
might solve it, only to be informed it's a classical problem with a standard
solution pattern developed by someone in Greece 2000 years ago.

~~~
iamwil
curious. What was the classical problem?

~~~
evv555
[https://en.wikipedia.org/wiki/Problem_of_universals](https://en.wikipedia.org/wiki/Problem_of_universals)

------
prewett
I think part of the problem is that MVC is pretty heavyweight. Most UI doesn't
need that kind of flexibility, but when you want it, you want it. So you need
a way to make it simple most of the time and still have access to the details.

In web development it is probably complicated by that fact that, in my
opinion, declarative positioning and sizing of elements is a pipe dream. It
_looks_ simple until you try to actually implement it, and HTML/CSS has only a
rudimentary implementation. (As far as I know, Motif and Apple's constraints
are the only UI toolkits that have a solid implementation) Given what we want
to do with the web these days, I think we would be better off with programming
the web page declaratively. Something like what Qt does. I've never found an
easier way to write a UI than Qt.

~~~
brightball
You nailed it.

MVC was popularized because after enough people went and just threw together
random things for enough projects, turnover, learning curve, switching between
projects, etc just became a huge burden. The big sales pitch for MVC on the
web (largely influenced via Rails) was a good enough common structure for web
apps that developers could learn and apply across projects.

It worked in that regard, but as usage became more popular we ended up adding
on more and more and more and more to try to make the "common" solve
everything. Constant changes screw the entire point of the "we all learned and
know this" benefit.

Flexibility of your approach is probably more important in the world today
than following a rigid structure in an attempt to let the structure solve
everything.

I like the approach outlined here...but I'd have a hard time using a framework
based on it. I'd rather write my own code using a simplified process and
minimizing dependencies if I'm going outside of something that's clearly a
major player that can be counted on to stick around.

~~~
coliveira
You just mentioned something very important: minimizing dependencies. Open
source frameworks are sold as a way to minimize development complexity, but
they add the big pain of depending on external packages that frequently change
without notice. If you develop you own code, at least you know what and how
things changed.

~~~
superuser2
>frequently change without notice

Unless you are doing something so spectacularly, mind-blowingly irresponsible
in your dependency management that changes just come in of their own accord
(i.e. Go's defaults), no they don't. They change when you choose to vendor the
new version or change the pinned version number.

It's true that your dependencies won't get security updates until you decide
to upgrade, but other people are certainly not writing security updates for
your in-house code.

You should care about the code quality of the 3rd party libraries you use,
with the understanding that you might one day take over maintenance of them,
at least for internal purposes. That's still not a reason to duplicate effort.

------
carsongross
He nails the problem: API bloat due to chaotic front end needs, but there is a
_much, much simpler_ solution: move the UI/DOM building back to the server
side.

This gives you a nice, secure environment to build your UI in with the full
power of the query language your datastore provides, and it doesn't require
any particularly complex architecture or discipline to maintain.

And, of course, I would be remiss if I didn't mention my baby,
[http://intercoolerjs.org/](http://intercoolerjs.org/), as a tool to help you
do it.

~~~
aikah
> move the UI/DOM building back to the server side

> Intercooler responses are HTML fragments.

I'd argue that, just like described at the end of the article, it's just
shifting the burden on the server. It's a trade off.

IMHO React gets a lot of things right :

\- DOM diffing

\- Components

\- 1 model as a unique source of truth

And when one thinks about it, IT IS MVC in its purest form, since there is
only one model, one big view(the tree of components) and one controller(using
event delegation). What React nailed is an efficient way to rerender the view.

~~~
carsongross
React doesn't solve the fundamental problem of either API churn or security
issues in browser client code. It may be elegant (I don't think it is) but it
is orthogonal to the issue at hand.

Server side MVC and HTML as a transport has a huge number of advantages, not
the least that HATEOS "Just Works" without anyone having to think about it,
but even if it didn't, I would think that the API churn/security tradeoff
would give the development community pause about heavy client-side logic.

~~~
Silhouette
_React doesn 't solve the fundamental problem of either API churn or security
issues in browser client code._

I'm not sure what problems you are referring to here, since you don't seem to
have defined them anywhere. They sound like they'd be well outside the scope
of a library like React, though, which is essentially just a declarative UI
rendering tool.

------
halayli
He starts with a negative tone when describing react & redux without backing
up his negatively with proper & convincing arguments just so that later he can
throw in his alternative solution.

I don't know why we keep doing it but often times we cover our eyes on purpose
and brush off existing solutions backed by thousands of engineers so that it's
easier to make our points.

~~~
Lazare
Especially considering his proposed solutions looks an awfully lot like not-
very-fleshed-out remakes of React and Redux.

~~~
jdubray
This is not true, please visit the SAM room on Gitter
[https://gitter.im/jdubray/sam](https://gitter.im/jdubray/sam)

In a nutshell:

in redux the reducer updates the model as: state.counter += 1 ;

All SAM suggests is that this is an unfortunate coupling, you should write it
as: // action function increment(value) { return value + 1 ; }

and then present the output of the action to the model:

state.counter = data.counter ;

Redux does not have any next-action-predicate either.

~~~
halayli
That's not true either. In Redux the reducer is always pure and never modifies
its arguments, at least in principle. It returns a new copy representing the
new state. Dan Ahramov relies on deep-freeze to always assert this fact in all
of his tutorials.

Regarding next-action, in Redux subscribers are called after the root reducer
returns the new state. You can always call dispatch from a subscriber.

You and Sam are proving my point by not actually taking the time to understand
the existing solutions.

------
phantom_package
Isn't GraphQL/Relay (or similar tools) the solution here? Has the best of
custom endpoints (can be conceptualized as a single, infinitely customizable
custom endpoint) without the drawbacks (there's only one endpoint, and backend
engineers just need to expose a schema).

It was kinda disappointing to see him fail to properly address tools that were
designed to resolve his original concern. He basically decides that GraphQL
forces you to "shape your models to your views" (which is false, GraphQL/Relay
just collates and trims your models before delivering them to your views). In
a sense, it allows him to continue to say "yes" to his frontend developers
(which is good from a product standpoint) without adding a ton of custom
endpoints.

------
scotty79
I'm not sure why author dismisses graphql. It greatly simplifies server-side
work. You just need to implement one endpoint that responds accurately and
quickly to a composed query in accordance to what rights the current user has.
It's not as easy as "serve result of SELECT *" but it's well defined and
flexible for consumers.

~~~
c17r
Agree. His opening complaint is from the Front End saying "I need x, y, and z
so make me an API that returns {x, y, z}" which he wouldn't need to do for
them if they were using GraphQL.

~~~
weq
IQueryable. Go look it up. MS did GraphQL years ago.

If you got out of your insurlar JS/FB/Twitter bubble, u will see the anti-
pattern that IQueryable become.

~~~
scotty79
I don't think IQueryable is very composable.

It goes bit beyond simple query builder because it can automatically translate
for you more expressive queries into SQL
([http://www.infoq.com/presentations/theory-language-
integrate...](http://www.infoq.com/presentations/theory-language-integrated-
query) ) But I don't think people could define parts of IQueryable in .ascx
files and compose it into single IQueryable result of which feeds the
components. That's the main idea of graphql.

~~~
hokkos
GraphQL is "structurally typed" where IQueryable is nominally typed by its
generic argument. This make GraphQL more easily composable, but IQueryable is
still composable with functions.

------
norswap
I always find it interesting how something seemingly as simple (conceptually
speaking) as building a web app can in truth turn out pretty darn complicated.

I'm not seeing all the complexity we see here or in other frameworks is
warranted, but clearly there is something going on making this quite hard.

I'd be interested to see fundamental research (and vulgarization thereof) on
this.

~~~
tracker1
Maybe because there is more to creating a usable interface that can have
multiple points of operation from a user perspective than the underlying data
storage or API interfaces. Developers that concentrate heavily on backend data
interfaces think their worlds are so important and have spent so much time
looking down on the front end that now, when better front ends are demanded,
they fall apart trying to create them... The same does happen in reverse,
designers tend to want certain types of interfaces and workflows that are
simply hard to manage in any practical way.

The difference is that now, more people on both sides of the spectrum are
starting to gain insight into the rest, and starting to realize that good
"full stack" development is hard. There are also nearly infinite options, and
even more opinions.

------
velox_io
Changing the API design because a frontend dev doesn't like the style is
definitely an anti-pattern. Customising APIs for every imaginable use case
will get painful fast!

Angular does have powerful services to transform objects. For example last
week a library (ngTagInput) was expecting a list of objects with {id, name}
however the server was returning a list of integer id's. It was trivial to
replace the id with the {id, name} object in the service, without requiring
changes to either the library or the back end - the API is still generic.

~~~
plaguuuuuu
APIs should be designed such that the total effort to build both sides of the
equation is minimised. APIs are, after all, designed for consumption - you can
return data in any number of formats - eg a proprietary binary format, or
whatever, but if your consumers find it hard to use, then the API sucks. End
of story.

~~~
mettamage
Curious to what extent you stand by this statement -- as an exploration not a
refutation ;) So lets stretch it to the limits. Lets create an API for a non-
programmer. For example, lets allow him to make a survey in iOS.

You could, for example, create an Excel file -- lets assume these non-
programmers know Excel a bit. One column could designate a template, another
column could be used for the question. Perhaps a column for materials (e.g.
video files or images). I guess the point is clear, you could make columns
that do something specific in the app. Add some documentation and presto, you
have an API for non-programmers :)

The Excel file itself could be given to a programmer who implements it or it
could be uploaded to some automated process that spits out an iOS app. A
rudimentary version could for example attach some pre-specified views with
some questions and images.

What do you think, is it possible to create an API for non-programmers via
some software that they do know?

------
romanovcode
The reason I choose to work with MVC frameworks is because more often than not
other people work on my code with me.

If I would create my own abstractions it would be good for me but very, very
bad for others.

------
mej10
If you are serious about front-end Javascript, you owe it to yourself to check
out the ClojureScript libraries Reagent (and re-frame) and Om.Next.

~~~
pandeiro
Aside from the pithy syntax compared to even the most futuristic ECMAScript,
meaning frontend code is faster and easier to write (and throw away, if need
be), there's another key element Clojure brings to solving this API
proliferation problem, which is just how easy it is to do data
transformations. The Clojure standard lib makes it trivial (dare I say, fun?)
to carve up and reshape whatever data you're consuming to fit the model your
application needs.

------
pluma
First he dismisses React, then he says his code is looking a lot like React
without the ceremony, then he shows code samples that look a lot like React
except they use string concatenation (hello XSS) to build the DOM (goodbye DOM
diffing) and instead of following the modern React idea of small composable
components they are huge and bloated.

Is this satire?

~~~
marrs
I thought he was quite positive about React, but he seemed to be uncomfortable
with their lack of provision for the model layer.

------
al2o3cr
From one of the screenshots:

    
    
        div class="opacity-'+slider.maskOpacity
    

Even better once you notice the actual inline `style` attribute two lines up.
_headdesk_

~~~
tommoor
It's almost as if just about anyone can write a blog post on the internet :)

------
wereHamster
WTF? Blindly concatenating strings... hello XSS..

------
pearjuice
It's a typical Hacker News cliche: "Why I No Longer Use [commonly accepted
standard]" but I am honestly glad that the author put a lot of effort into
explaining the theoretical AND practical concepts behind his stance. So in
case you skipped the article because it fell through your "textbook HN hit"
filter, please take my word for it that it's worth reading.

------
djfm
Can't really see how the proposed solution is different from React + Redux.

------
jondubois
Not using an MVC framework is often fine if you're working alone on a project
but you might just end up reinventing angular...

Then when new people come in to your project, the learning curve for them will
be steeper than Angular - Also you won't be able to hire any 'batteries-
included' programmers because nobody will know your framework when they join
your company.

Worse, engineers might refuse to join your company if they see that you've
built a custom solution from scratch... Chances are that your framework won't
be as good as Angular or React.

Maybe you should try Google's Polymer framework? I've tried all the major ones
and Polymer is the least 'frameworky' one.

~~~
matzipan
Also, you won't benefit from the ready-made modules that are available out
there.

------
sbov
I feel like part of the "problem" of API churn is because we are writing APIs
that live in the controller layer. Just because it runs on the back end
doesn't mean it lies within the model layer.

Beyond that, it certainly makes for less code to make the model directly line
up with the view, but you create coupling between the two. This seems like a
major difference between MVC I've experienced in the web vs desktop apps back
in the late 90's - in a desktop app my view didn't rely on the model's _code_
, just on the model's _data_. But nowadays with rails and spring and django
the view is coupled directly to model _code_.

------
EGreg
Reading this I am kind of happy we rolled our own framework and dogfooded it
for the past 5 years.

It has only a few concepts:

    
    
      * Pages (webpages)
      * Tools (components)
      * Events
      * Users (accounts)
      * Streams (data)
    

Everything is accomplished around these basic concepts.

[http://qbix.com/platform/guide/features](http://qbix.com/platform/guide/features)

~~~
onion2k
That's always going to lead to a solution you like (because you built it) but
it loses the advantages of open source in both "many eyes" where the code gets
_massive_ amounts of testing and "prior knowledge" where you can recruit new
people who already have some knowledge of the technology you use. Neither of
those are necessities, of course, but they're definitely useful advantages.

------
jijji
The problem with MVC is that there is no clear definition of what it is, and
so what you're left with is people who are putting code in the View, code in
the Model and code in the Controller. Then, go try and debug that. You wind up
having to logging basename(__FILE__) to understand what file is responsible
for what. It is a nightmare for debugging. Then you have to to talk about the
elephant in the room -- performance. Performance using MVC frameworks is
orders of magnitude slower than using straight procedural or functional
development. It should not take a rocket scientist to understand that calling
a function directly is faster than instantiating an object and then
abstracting an abstraction from an abstraction from abstraction just to return
a result. I dont know why people do it, but I find myself cleaning up the mess
more often than not. You cannot convince me that a 10x decrease in performance
and a 10x increase in code complexity is a good thing.

------
drostie
Searching through the comments here, only one of them mentions SAM, which is
the point of the article. Some nuanced thought about what's going on here is
therefore warranted. So let's start with old-school Smalltalk's MVC: this was
a message-passing system consisting of three types of concurrent processes:

    
    
        * models maintain a list of "subscribers" that they regularly send certain 
          messages to, in response to the messages that they receive from the outside 
          world. This can as always involve the internal state that each process 
          maintains.
        * views subscribe to models and then present a graphical description of the 
          messages they receive. 
        * controllers listen to user-interface events from the view, and use it to send
          messages to models.
    

These have transformed mightily in the intervening years; a model these days
often refers to some form of schema for data structures which are returned by
services; controllers often query those services and provide them to the view;
views may define their own service-queries. Often there is no clear notion of
subscription except possibly subscribing to events from the GUI, which is the
responsibility of the controller; the controller basically handles everything
which isn't either the structuring of data or the organization of the display
components.

SAM appears to be coming from the latter developments and is concerned with an
associated explosion: Every view and interaction more or less gets its own
service on the back-end, providing a sprawling codebase which resists
refactors; they also get their own controllers which maintain them.

In the SAM idea, the model now reprises its earlier notion of managing
subscribers and containing business logic: however it is now "dumbed down"
from its potentially-very-general Smalltalk definition: the model is instead
meant to hold and maintain a single data-structure. (Can there be multiple
concurrent models?) The model apparently only receives requests for an all-at-
once update, but it may decide to transform its state `new_state =
f(old_state, proposed_state)`. Presumably then it again tells its subscribers
about the new state if it is not identical to the old state. (Each view is
expected to compute the diff itself, probably?)

A "state" in SAM appears to be identified with a "view": a "state-
representation" is a function from a model to a DOM. Your GUI consists of a
bunch of these, and hypothetically we can diff the DOM trees to better
understand what needs to change on an update of the related model properties;
the "view" is basically just a bunch of representations of the underlying
state with some "actions." These "actions" are not actually parallel processes
at all but do take the classical responsibility of the "controller", routing
user-interface events to messages to send to the model. The apparent point
here is that they should correspondingly be very "dumb" controllers: they just
create a transformed version of the data that they received from the model and
then send it back to the model as a "nomination" for a possible change.

Finally there appears to be a strange next-action callback which may be part
of every "view update." (It's not clear where this lives -- in the "action"?)
I am not entirely sure why this exists, but it may be that the algebra of
actions without this callback is merely an applicative functor, not a full
monad. The essential idea here is that the function apparently can compute a
follow-up action if such needs to happen.

If I'm understanding this correctly, then a simple app which seems relatively
hard to structure this way would contain:

    
    
        * a counter stored in a database,
        * a button which should ideally increment that counter,
        * a display showing the current value of the counter,
        * a notification window telling you when your click has updated the counter.
    

I'm using a counter since it's got a nice algebra for dealing with coincident
updates; if someone else updates the counter then your update commutes with
theirs, saving the client-side complexity.

Without a framework, we would simply define two endpoints: GET /count (or so)
gets the current count; POST /increment will increment the current counter and
will say "Success! The current count is now: ____", telling you what you
changed the count to.

Here it seems like you need three models. First we have the server-side model
of what's going on:

    
    
        server model Counter:
            private count, Subscribers
            message increment(intended_count): 
                if intended_count == count + 1:
                    count += 1
                    Subscribers.notifyAll()
                    return ('success', count)
                else:
                    return ('failure', count)
            message count():
                return count
    

The requirement that we only nominate new versions of the underlying data-
structure means that we cannot just define the appropriate increment service
which always succeeds, but must instead tell the client that the request has
failed sometimes. Then there are two models on the client side: one holds a
list of outstanding requests to increment (updated by actions, retrying any
failures) and the other one holds the currently-cached value of the server-
side data (because we need to update this by both the former client-model's
update events as well as by some automatic process). You would probably
condense these in practice into one model, however they are different
concerns. The former model, however, is absolutely required, as it provides a
way for the "notification window view" to appear and disappear when one of the
requests has succeeded.

This seems unnecessarily complicated given the simple solution in terms of two
API endpoints -- however it does indeed fulfill its desire for lower API bloat
and some separation of concerns.

------
hyperpape
I was intrigued enough to look at the source of his Star library
([https://bitbucket.org/jdubray/star-
javascript/src/5806219be6...](https://bitbucket.org/jdubray/star-
javascript/src/5806219be6d37bfed9fbba9122e0d8f6de584140?at=default)), and got
very little out of it. Aside from a few truly strange things
([https://bitbucket.org/jdubray/star-
javascript/src/5806219be6...](https://bitbucket.org/jdubray/star-
javascript/src/5806219be6d37bfed9fbba9122e0d8f6de584140/src/core/exception.js?at=default&fileviewer=file-
view-default)), it's just generally not commented or documented, and I have a
hard time figuring out how it serves the goals of that article.

I'll take another look later, but I'm curious if anyone else got much out of
it?

~~~
jdubray
I am happy to walk you through, here are some links that show how I got there:
[http://www.ebpml.org/blog15/2014/12/tla/](http://www.ebpml.org/blog15/2014/12/tla/)
[http://www.ebpml.org/blog15/2015/01/tla-the-die-hard-
problem...](http://www.ebpml.org/blog15/2015/01/tla-the-die-hard-problem/)
[http://www.ebpml.org/blog15/2015/01/state-machines-and-
compu...](http://www.ebpml.org/blog15/2015/01/state-machines-and-computing/)
[http://www.ebpml.org/blog15/2015/04/star-based-component-
mod...](http://www.ebpml.org/blog15/2015/04/star-based-component-model-with-
tla-semantics/) [http://www.ebpml.org/blog15/2015/06/sam-the-state-action-
mod...](http://www.ebpml.org/blog15/2015/06/sam-the-state-action-model-
pattern/)

------
emergentcypher
I don't think MVC belongs on server-side web frameworks at all. It's not a
continuously updating interactive display, it's a one-off thing. You don't
have a model object sitting around sending messages to the view when it
updates. This doesn't happen. There is no triangle of messaging. What really
happens is a request comes in, and your "controller" is the one doing all the
calling.

The HTTP server is by its very nature a pipelined or layered application.
Requests are turned into responses through a series of transformations. They
go down the layers as they work their way to your database, and back up the
layers as they are built into responses. This is, incidentally, why functional
programming is such a great fit for web servers.

------
andraganescu
<< As a veteran MDE practitioner, I can assure you that you are infinitely
better off writing code than metadata, be it as a template or a complex query
language like GraphQL. >>

Reading it is worthwhile if only for this phrase.

------
ivan_ah
I'm not super convinced OP's SAM architecture is that revolutionary. It will
take something waay better to displace the current champion: React+Redux.

And speaking of the champion, here's a good write up[1] about tfb's helper
library 'react-redux-provide' that automatically matches names in this.props
with Redux actions and reducer outputs. It's a simple thing, but tremendously
reduces the wiring boilerplate for React+Redux apps.

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

------
dh997
Controllers are important for being gatekeepers, which can be adjusted (think
middlewares which add security, logging or other changes uniformly) and
inspected outside of the MVC code, and separates outside from inside.

It might be worth the tradeoff in the short-term, but it's the lifecycle TCO
of code counting support and modifications over many projects which will
validate or invalidate a particular approach (there is also a cost in terms of
hiring and learning curve for inventing an alternate convention).

I hope it works out.

------
ciscoheat
It happens time and again, another pattern from the programmers perspective,
when MVC really is much more than a pattern, and it includes the users
perspective. It's not about separation primarily, that's the nerd's view.

I've made an attempt to clarify what MVC is really about. It was posted here
before, I appreciate if you read it:
[https://news.ycombinator.com/item?id=10730047](https://news.ycombinator.com/item?id=10730047)

------
dclowd9901
First, his rocket example won't even work (in the actions.decrement function,
"'model' has not been declared"), but what he's talking about isn't actually
new in React land.

[https://github.com/chenglou/react-motion](https://github.com/chenglou/react-
motion)

Not that every idea has to be novel, but I think the code in this repo
provides a far better example of FRP (which SAM is) than that article.

------
falsedan
Please colleges, please make computer science/software engineering students
take at least one course where they have to write essays to pass the course.

~~~
mettamage
They don't, unfortunately. In my case I was very lucky. One of the first
things I did was Google about what programmers would do -- as opposed to
programming which I was scared of in the beginning days -- and I found out
about Joel Spolsky very early on in my studies. Getting a bit of breadth about
the culture and more about the philosophies and theoretical underpinning, from
various writers, has been quite helpful to me.

This is what he said:
[http://www.joelonsoftware.com/articles/CollegeAdvice.html](http://www.joelonsoftware.com/articles/CollegeAdvice.html)

You may guess what his number one tip is ;)

My number 1 'hack' that I learned from these classes is to eliminate every
unnecessary word and be as short and concise as possible. That way, I make
fewer mistakes, get my point faster across and I communicate more clearly in
general since there's no risk of being long winded. I never do it in HN
comments though, it takes a lot of time.

~~~
falsedan
My number one hack is to take the conclusion from the third paragraph/wherever
and, since it's the most important thing to communicate, move it to be the
first part (in front of all the tedious "here's the background on the problem
we were trying to solve").

------
soundoflight
I've worked on proprietary frameworks very similiar to what the author
describes. They are great for the web and in my opinion allow for tighter
code. The issue is that I haven't found a good, open-source one for the web.

Also, interesting, is the fact that computer engineer "coding" is much more
into the state concepts brought up in the article.

------
franciscop
There's an excellent tool to avoid the default value mess shown there:
defaults

[https://github.com/tmpvar/defaults](https://github.com/tmpvar/defaults)

It will fill your option object with the data if it's undefined

~~~
carterehsmith
Also, if he ever needs to check if a variable is a number, there is another
one-line-of-JS project on npm that does just that!

~~~
franciscop
But it _isn 't_ one line:

    
    
        var clone = require('clone');
        module.exports = function(options, defaults) {
          options = options || {};
          Object.keys(defaults).forEach(function(key) {
            if (typeof options[key] === 'undefined') {
              options[key] = clone(defaults[key]);
            }
          });
          return options;
        };
    

Besides the tests and the fact that someone is maintaining it. It's not much,
but it's code that doesn't have to be maintained by you

------
niutech
MVC, in a strict sense, as in Gang of Four, almost does not exists in
JavaScript frameworks. What we see is MVP (Backbone.js, Riot.js), or MVVM
(KnockoutJS, AngularJS). ReactJS prvides just a View.

------
LAMike
I think the author might like the simplicity of something like Vue.js

------
colemannerd
Cool abstraction, but would love to see actual code implementation.

~~~
jdubray
[https://bitbucket.org/snippets/jdubray/](https://bitbucket.org/snippets/jdubray/)
Can also share more code privately

------
kensign
[http://aurelia.io](http://aurelia.io)

------
mongosucks
pub/sub is the best, call it command bus, call it Flux, Redux,...

~~~
Lazare
Ah, but _my_ version of pub/sub is much better than the others, because they
don't adhere to the fundamental principles of pub/sub which I have derived[1].

[1]: I have discovered a truly marvellous proof of these principles, which
this comment is too small to contain.

------
abledon
This was a sobering read.

------
known
"Premature optimization is the root of all evil" \-- Knuth

------
fabrigm
Because you have time?

------
xyzzy4
I prefer the "VC" style (MVC minus the M). It is way too much work to have to
redefine your models on both the client side and server side, when you can
simply have all the data in temporary dictionary structures. You define your
models just once in the database itself. I don't know if anyone else does
this, but it keeps the amount of code to a minimum.

~~~
ralmidani
I use Django on the server, with Ember on the client-side. Without a concrete
model layer in the client that has computed properties and, to a lesser
extent, observers, things that were trivial to implement would become much
more difficult.

Of course, I look forward to the day when we can write our models once for
both the server and the client, but I've yet to see a "full-stack" solution
compelling enough to get me to abandon both Django and Ember.

~~~
sheldonb
To be fair, and if I'm understanding you correctly, you can use ember-data
alongside Ember to get your model layer (or even just use plain Ember.Objects
as needed).

Ember fastboot seems like it'll address some of your concerns too - it'll
allow for initial rendering of a page on the server with the intention of the
client taking over after that.

~~~
ralmidani
I use Ember Data along with Ember. Ember Data is my model layer. I should have
made that more clear.

As for FastBoot, correct me if I'm wrong, but right now it supports rendering
static pages for SEO. This is not useful for business apps. Rehydration on the
client-side (what you seem to be referring to) is still being worked on. But
it does not replace the server-side application.

At any rate, eventually someone will bring together the best of server and
client technologies in one full-stack package. With all due respect to what's
out there now, I haven't seen anything approaching the elegance of Ember and
Django.

