Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I and my co-worker are developing a web application with rails and node.js and we can't reach a consensus regarding a particular architectural decision.

Our setup is basically a rails server working with node.js and redis, when a client makes a http request to our rails API in some cases our rails application posts the response to a redis database and then node.js transmits the response via websocket.

Our disagreement occurs in the following point: my co-worker thinks that using node.js to send data to clients is somewhat business logic and should be inside the model, so in the first code he wrote he used commands of broadcast in callbacks and other places of the model, he's convinced that the models are the best place for the interaction between rails and node.

I on the other hand think that using node.js belongs to the runtime realm, my take is that the broadcast commands and other node.js interactions should be in the controller and should only be used in a model if passed through a well defined interface, just like the situation when a model needs to access the current user of a session.

At this point we're tired of arguing over this same thing and our discussion consists in us repeating to ourselves our same opinions over and over. Could anyone, preferably with experience in the same setup, give us an unambiguous response saying which solution is more adequate and why it is?

share|improve this question
6  
This smells a lot like you're just using a bunch of technologies for fun instead of purposefully. Rails or Node.js, pick one. If you think you have cause for using both I would like to hear your explanation of reasoning behind that. (I know of good reasons for using both, it just doesn't sound like you have them off hand). Also, if you aren't using Redis for actual cache but rather as your pub-sub provider A) there are other products focussed on pub-sub, and B) when you settle on rails-only you won't need to pub-sub stuff to Node.js anymore. –  Jimmy Hoffa Oct 15 '13 at 13:16
    
Not really, we're building a real world app, we use node.js for realtime stuff. We plan to eventually use only node.js, or rails live streaming if we migrate to rails 4. –  lpvn Oct 15 '13 at 13:21
    
Node.js is ideal for long-running IO, but it sounds like all your using it for is WebSockets. Rails does WebSockets just fine and would integrate more naturally with the rest of your system which is already in Rails by the way I read this. I didn't say you weren't building a real world app, it just sounds like you weren't picky with your technologies. I wouldn't argue about whether the websocket belongs in Node.js or Rails, I'd argue about whether you want your website to run on Node.js or Rails, and get rid of the other one. They're both fine choices but they're redundant in your use case –  Jimmy Hoffa Oct 15 '13 at 13:26
1  
Also, nobody can tell you where to put the WebSocket communication until you explain some of the actual behaviour and requirements of the system and what exactly you are using Rails and Node.js for. Without those details this question is relatively unanswerable because the decision of where to put the WebSocket hinges on your specific architecture/usage of these technologies. –  Jimmy Hoffa Oct 15 '13 at 13:51
    
As I stated we'll eventually get rid of one of them, it'd be better to be using just one of them, Im not disputing this. The part I'm not so sure is when you say that websockets is a solved problem inside the rails ecosystem, Live Streaming maybe? It's only for rails 4 and is still beta(at least it used to be when I read about it not much time ago). We're using websockets to send realtime messages to many clients. I'd love to read from you an answer about a railsonly solution for our problem of real time client server communication though, telling us our setup is wrong/redundant isn't helping. –  lpvn Oct 15 '13 at 14:10
add comment

2 Answers

up vote 0 down vote accepted

Seeing your clarification, and since you want developers' opinions, here's my $0.02. I would call Announce from inside your controllers, for two reasons. First, I tend to see ActiveRecord callbacks as being a kind of "implicit"/"passive" calling of an action. ActiveRecord makes sure to run those callbacks for you and -- unless they break -- you don't really pay much attention to them again. You don't have to call them manually; they tend to minor, routine sorts of matters.

This working assumption I've always had leads into the second reason for me: returning a response client-side is an "active", realtime process, and by rights should be something explicitly invoked and viewable in the more "active" side of your codebase (viz., the controllers). Returning responses back to a browser (whether via Rails, Node, &c.) are more of a controller's responsibility, and the Rails framework is geared toward that kind of setup.

share|improve this answer
add comment

Actually (without knowing more of the details of your architecture or your domain), this situation would be a great fit for a service object---as an occasional mediator object between your controller and your models.

Call it WebSocketsService or BroadcastService, or whatever you like. Make it a singleton (either using the Ruby singleton stuff in std lib, or perhaps a Module extending itself with some methods tacked onto it), and access it from either the controller, or from a model.

Your controller could invoke it:

WebSocketsService.broadcast(my_model, "this message!")

...and likewise for your models. You mentioned above the possibility of going through a "well-defined interface": something like this might be it.

module WebSocketsService
  extend self

  def broadcast(model, message)
    ## interact with Node here...
  end

end

If you decide to go to an Rails-only solution in the future, the only thing you'll have to change is the implementation inside these methods. Neither the controllers nor the models involved would need to know.

I just add a /services directory inside of /app to keep them all.

Just an idea I hadn't seen mentioned above.

share|improve this answer
    
We're already doing this, we created a service class called Announce that has the functionality you described above but this does not answer what I asked. I asked what the best place to call Announce is, in the controller after saving an ActiveRecord object or in the after_save callback of this object, for example. Both will work for sure but one of the alternatives sounds wrong in term of best software engineer practices, so I asked this questions in order to know some opinions of other fellow programmers. –  lpvn Oct 16 '13 at 23:06
    
@lpvn: I'm sorry that my response "did not answer the question you asked." Your original question was verbose yet unclear in several details, and one could read what you had written and assumed you meant the placement of the logic for such interactions being located in controller vs. model, not the invocation of a third object containing that logic in either of those places. Your clarification above, regarding your Announce class, etc., makes your dilemma much clearer. But you didn't "ask what the best place to call Announce was" in your original question, so please be more patient. –  tj071978 Oct 17 '13 at 14:29
    
Sorry for the harsh language, it's hard to be clear about something if you spent too much time over it. –  lpvn Oct 23 '13 at 22:02
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.