Leaena

Work From Home Friday: Playing Around With Node

Aug
21

Time to add another weekly to the mix. At my office I generally work from home on Fridays because it was a tradition before me and who am I to break a tradition? At my last job it was Thursdays, but it’s awesome that most eng jobs understand and allow for the space to get shit done with out distractions.

As part of my Fridays from now on, I’d like to carve a bit out of my day and just go down a rabbit hole. Most of them will be tech related (most of which will be frontend) but I’m not going to put a label on this segment other than the fact that it will probably not be quite as detailed (all though I say that now and then this one turned out to be a monster). Some weeks it might even be me just throwing up some links and commenting.

Cat in a box

So lets start easy this week by opening the Pandora’s box that is Node.js. In my scant spare time I’m working on a side project that is essentially just an API with some munging of data. HOWEVER, I’ve grown bored with my standard Node/Express workflow and wonder if there’s anything newer or more exciting to play with. Lets find out together shall we?

So I’ve heard of some other alternatives, but haven’t really dove into Node stacks in a while because I’ve been a Python girl up until recently. So, let’s be lame and google alternatives to express.js (what, you were expecting high-tech sleuthing?). Immediately the apparent new darling Koa is all up in my grill. So Koa is all ES6 ES2015 – whatever I’m sticking with ES6, it’s not like we’re all going to magically start using ES2015 in 2015 anyway. The initial footprint is small, but you can’t do much with it without additional middleware.

Koa has always been something that I’ve kinda prodded at with a stick and never done much with. Each time I read about it I find it more and more interesting, but it seems like it would be overly complex for my small personal stuff. Besides being ES6 opinionated, you’re basically free to add whatever you want. You can use established middleware or roll your own without too much effort. For my small side project though, I just don’t have the energy to research yet another step of deciding which middleware to use or creating it all from scratch.

And then there’s the other standard in a trifecta of frameworks that everyone talks about called Hapi. I have never gone beyond looking at the Hapi documentation and going “nope!” but that’s just a personal opinion because I just don’t like the look of using objects everywhere for everything. It gives me Backbone flashbacks and I just can’t handle it. So I don’t have much to say about Hapi, but will take this to an aside that I enjoy how much like art coding is. I can have feelings about the tools I use. It may be amazing for someone else, but if I’m just not feeling it, I generally have other options.

So lets narrow it down, what I really want is an API layer. I don’t care as much about rendering pages. So lets keep going. A couple of new contenders – Restify and Loopback. Both seem decent, but I’m a sucker for not having to do as much work and we use Ruby at my new job so I love it when I don’t have to define all of my routes by hand. Loopback is also a part of something called StrongLoop, which I’ll admit I haven’t heard of before but seems to have some Node enterprise and monitoring apps. Oh… and it’s built atop Express. We have come full circle my old friend.

Alright, lets walk through the tutorial. I have mixed feelings about generators since they usually throw waaaaaay more at me than I will ever need, but FOR SCIENCE!

How Cute

I told you it was for science. Alright, so before I create any models, I decided to poke around at the code generated. And I am immediately vaguely displeased. It includes a .editorconfig file, which while in sync with the configuration settings I generally use seems annoying to impose on someone. Also it generated a looooot of files. They seem orderly though, so lets press on.

And now I’m lost. This is not in the tutorial. -1 for out of date tutorial! Time to break out the docs!

In general, use PersistedModel as the base model when you want to store your data in a database using a connector such as MySQL or MongoDB.  Use Model as the base for models that don’t have CRUD semantics, for example, using connectors such as SOAP and REST.

+5 for helpful docs. The other models are actually pretty cool too and I could see myself using them quite a bit in larger applications, but for now lets stick with PersistedModel.

And there you have it! I now have a person model! It’s some pretty json that’s easy to read and understand. So in summary: Loopback/StrongLoop reminds me immensely of Rails, which I’m OK with. I think I will continue to play with it, but so far it gets a thumbs up from me.

As an aside: For those wondering, I’m using the Peppermint theme with a basic bash terminal, though I do recommend zsh/ohmyzsh and use that at work. I also use Sublime Text with the theme & color scheme itg.flat – Dark.

Programming, Work From Home Friday , , , , , , , Comments Off on Work From Home Friday: Playing Around With Node

Setting Up a Database Node Module on a Node/Express Server with Sequelize

Dec
29

If you just need to get a node server up and running with very few lines of code then you hopefully already know about Node/Express (if you don’t, the Express website has a pretty good intro tutorial and has good documentation to get started serving up static assets). If you need all of that and to be able to route queries to a database quickly and easily then you might not know about the awesome power of Sequelize.

If you haven’t messed around with a ORM (Object Relational Mapper, a program that maps your code to a database) before, Sequelize is a really straight forward one to start with.

var voteTable = sequelize.define('vote', {
  video_id: Sequelize.STRING,
  timestamp: Sequelize.INTEGER,
  vote: Sequelize.INTEGER
});

voteTable.sync();

Once I had my server set up (and installed the sequelize dependencies). This was the line of code I needed to use to create a new table for my current group project. Sequelize automatically includes extra columns like unique id and created at/updated at timestamps (there are ways to tell it not to too).

The rest of the initial set up is easy too, but it’s well documented over in the Sequelize docs. The fun part comes when you can start to make your database more modular. The first thing I did was to take out the actual username/password information from my database connection. I stored them as an object in a separate JavaScript file (so I could add it to .gitignore and not share my passwords with the world).

//module.exports allows us to use this code in other places as a node module, 
//we'll see it again when I make the database calls modular
module.exports = { 
  database: 'database_name', 
  username: 'username', 
  password: 'secret_password',
  host: 'host_url',
  port: 5432,
  dialect: 'postgres', //obviously you don't have to use PostgreSQL
  native: true //required for Heroku Postgres (I'll cover that in another post)
};

I saved that snipped to a file called db_config.js at the root directory and then created my main database module in the subfolder /controller/ called database.js. So to have access to the private config object, all I need to do is set up my dependencies, import the db_config file, and I can start using my config variables to connect to my database:

var Sequelize = require('sequelize');
var pg = require('pg').native; //again this line is specific to using a Postgres database
var config = require('../db_config');

var sequelize = new Sequelize(config.database, config.username, config.password, {
  host: config.host,
  port: config.port,
  dialect: config.dialect,
  native: config.native //Heroku Postgress again
});

Now between that code and my creating a table I have full access to a database, but now I need to get this all into my main app.js simple server I created with Node/Express. This is a super easy leap. First I create my functions to send and retrieve data in /controller/database.js:


module.exports.createVote = function(req, res){
  //code to bundle up the created object and save it do the database
};

module.exports.getVotes = function(req, res){
  //code to find votes based on specific requests from the user
};

Now to have access to these functions (which are a part of the database.js node module, thanks to the module.exports object which is a feature of Node) I only need to require database.js in my main server app and call the functions where I need them:

var database = require('./controllers/database');

//many lines later
app.post('/votes', database.createVote);
app.get('/votes/:vidID', database.getVotes);

The /votes/:vidID is a handy trick of Express to pass information to the server. The value gets attached to the req.param.vidID property so I can use it when I request specific information from the server. For example if I wanted to query for results from a video ID of 123 I would send a post request to /votes/123 and then my req.param.vidID === 123.

One last trick, in Sequelize when you query the database you get back quite a few more rows than you might expect. When I query my voteTable (the one I only explicitly created three columns for?) I get back something that looks like this monster:

 { dataValues: 
     { video_id: '7QBgK0_RbkE', timestamp: 2, vote: 1, id: 192,
       createdAt: Sun Dec 22 2013 22:19:33 GMT-0800 (PST),
       updatedAt: Sun Dec 22 2013 22:19:33 GMT-0800 (PST) },
    __options: 
     { timestamps: true, createdAt: 'createdAt', updatedAt: 'updatedAt',
       deletedAt: 'deletedAt', touchedAt: 'touchedAt', instanceMethods: {}, classMethods: {}, 
       validate: {}, freezeTableName: false, underscored: false, syncOnAssociation: true,
       paranoid: false, whereCollection: [Object], schema: null, schemaDelimiter: '',
       language: 'en', defaultScope: null, scopes: null, hooks: [Object], omitNull: false, 
       hasPrimaryKeys: false },
    hasPrimaryKeys: false,
    selectedValues: 
     { video_id: '7QBgK0_RbkE', timestamp: 2, vote: 1, id: 192,
       createdAt: Sun Dec 22 2013 22:19:33 GMT-0800 (PST),
       updatedAt: Sun Dec 22 2013 22:19:33 GMT-0800 (PST) },
    __eagerlyLoadedAssociations: [],
    isDirty: false,
    isNewRecord: false,
    daoFactoryName: 'votes',
    daoFactory: 
     { options: [Object], name: 'votes', tableName: 'votes', rawAttributes: [Object],
       daoFactoryManager: [Object], associations: {}, scopeObj: {}, primaryKeys: {},
       primaryKeyCount: 0, hasPrimaryKeys: false, autoIncrementField: 'id', DAO: [Object] } 
 } 

And that’s just ONE entry in the database! To fix that add an option to your sequelize query: {raw: true} so the query would look like:

voteTable.findAll(query, {raw: true})

And one entry of output would be:

{ video_id: 'T-D1KVIuvjA',
    timestamp: 2,
    vote: 1,
    id: 1,
    createdAt: Sat Dec 21 2013 14:55:42 GMT-0800 (PST),
    updatedAt: Sat Dec 21 2013 14:55:42 GMT-0800 (PST) }

That is enough database tricks for today. If you want to just stare at my code for a while to create & retrieve votes from our database you can find my gist here (with sanitized login info for the db_config). The real (still being modded by the team) code is forked on my GitHub. I have a few more of these in the works from my adventures slinging code and I hope to post a few more before Hack Reactor starts back up and I lose all free time again.