Skip to content

Instantly share code, notes, and snippets.

@mikermcneil
Last active December 14, 2015 00:49
Show Gist options
  • Save mikermcneil/5001892 to your computer and use it in GitHub Desktop.
Save mikermcneil/5001892 to your computer and use it in GitHub Desktop.
What do you think of:
// UserController.js
module.exports = {
// The new way
test1: function() {
// contexual access to params
// (this is probably the most valuable piece-- normalizes stuff between req.params, req.query, req.body, and socket.io)
this.name;
// An object containing all params
// (that means a sane merge of the path params, the query string, and even the parsed HTTP body)
this.params;
// Send back an error (500)
return new Error('Something bad happened!');
// Send back a JSON response (200)
return {
success: true
};
},
// Diving deeper
test2: function (req,res) {
// But Mike, what about callbacks?
// Well, that part kind of sucks still..
// (not a lot we can do here, since javscript kills scope)
// Shortcut sends a 200
// string or JSON can be sent back
res.ok === res.send;
res.ok();
res.ok('optional string');
res.ok({message: 'or json'});
res.ok({message: 'or json'});
// Shortcut sends a 404
res.notFound() === res.send(404);
res.notFound('optional message');
res.notFound({message: 'or some json'});
// Shortcut sends a 500
res.send(500) === res.send(new Error) === res.error();
res.error('optional message');
res.error({message: 'or some json'});
// Example
User.find(this.id).done(function (err, user) {
if (err) {
return res.error(err);
}
else if (!user) {
return res.notFound();
}
else {
return res.ok();
}
});
// But in the future, we might be able to use deferred objects
// it's just that if you're doing anything with any modules that aren't a part of Sails, they won't necessarily work like this
// But for posterity: e.g.
return User.find(7);
// Sexy right? Maybe for this summer....! That's a tall order.
},
function test3 (req,res) {
// Anyways, what about realtime?
// Arbitrary broadcast to sockets in a room
this.broadcast({
something: 'a message'
}).to('roomname');
// Or leverage the model
// subscribe to all changes to any dog in the Dog collection
Dog.subscribe();
// subscribe to changes to dog #3
Dog.subscribe(3);
// publish the fact that a new Dog has been created
Dog.introduce();
// publish a message to all users subscribed to the Dog collection
Dog.publish();
// publish a message to all users subscribed to Dog #5
Dog.publish(5);
}
// But you can still get to req and res if you need them
// The "old way"
oldWay: function (req,res) {
// Req: params, headers, other raw request data
var bar = req.param('bar');
// And req.socket if you need direct access to socket.io
req.socket.broadcast.to('roomName').emit('enter',{
type: 'arbitrary message',
description: 'mustard is not nearly as delicious in my oatmeal'
});
// Direct control of HTTP/WS response
res.send(500);
}
}
@dcbartlett
Copy link

Looks spiffy. the only thing that would make a little more sense to me, but i don't know how implementable it is is to do

// subscribe to changes to dog #3
Dog(3).subscribe;

it just makes it a bit more readable. However i understand that this is probably not very easy to implement...infact almost impossable.

@mikermcneil
Copy link
Author

From Austin:

// contexual access to params
Forgive me if I've misunderstood this part, but does this mean if there's a name field in the query string you'll be able to access it via this.name? If that's so I'm not a fan, I feel like you risk polluting the namespace an unknowingly. Accessing things through params seems sufficient imo.

// An object containing all params
I like this, is it possible to access it without this. ?

I don't really have an opinion on test2. My only thing is that in rails I never really found myself having to deal with response codes, so I wonder if there's a way to just move all that into the framework somehow.

test3 looks good to me, but I haven't done enough realtime to have an opinion on the proposed solution yet.

Overall I feel like maybe there's too much magic going on, but then again, I'm not familiar with everything enough yet to actually see how much of an improvement this is over the current implementation.

@ErhanAbi
Copy link

Did you guys begun working on this? it would be quite nice to have those functionalities, but I know you're having alot of other things to do :). But alot of this kind of "automation" has it's disadvantages as well. I think you guys should get all the documentation in a single place. For example, it took me about 3-4 days to find how to chain controller methods. For example on a request execute method create from BooksController and then the update method from UsersController. And found it in one of your gists. My newest problem is, when chaining methods like this, how should I differentiate between responding to request or calling the next function. Right now next is a function. Always. I might be a newbie but I would lovely read documentation and figure out a way of doing this, cause my problem is very probable to have a solution, but it's kinda frustrating to search for a few days to find it. Anyway, keep up the very good work :)

@ErhanAbi
Copy link

Just thinking about this.What I said earlier applies when you build your API around resources. Thus a resource (e.g. User) can have a subresource, or a list of subresources (e.g. Books). When the user creates it makes a post to server to /api/users/:userid/books . In BooksController it is created the book and the execution continues to UsersController for updating the User (which has that book). I was thinking if it's a good (scalable) ideea to have a controller on it's own only for responding to API requests, let's call it ResponseController. thus the execution goes to BooksController (book created), then UsersController (user updated) then ResponseController which parses the req.responseObject (just a naming convention... could be named whatever...) property and ends the response with a res.json method. What do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment