After 4 year of waiting we had another World Cup full of surprises and once again I decided to do a football pool, or quiniela as called in Latin America, to scam all my friends… I mean to learn more. My first experience was on 2014 using PHP and Yii to create it but this time I wanted to learn something new and fresh.
I want to share my experience with Node and the solution I reached.
Note: This article is about my experience creating one of my first apps with Node and in no way an actual guide for beginners. If you are new to Node there are several guides you find that will help you more, including the official guide . Of course I’m always eager to help in any way I can.
I’ve been using Python for web development for the last years and every time I’m searching for news they are all talking about Node, so I decided to join the cool kid’s club and try it.
Me
Before starting I needed to set the rules for this year. I don’ think these are the standard rules but on my experience are extremely fun (specially on the last matches when a point or two can make you win):
(You can get the complete code here)
The first thing I needed to do was finding an structure that was easy to understand but at the same time scalable. Finally I decided to use an structure somewhat similar to Flask blueprints which I’m more familiar with (baby steps!).
api/|-- config.js|-- controllers| |-- database.js| `-- positions.js|-- matches| |-- index.js| `-- matches.js|-- teams| |-- index.js| `-- teams.js`-- users|-- index.js`-- users.js
This structure groups the functionality of each main feature of the API and views in a directory. Since this is a small project I used only an index file to expose the router and a single file to store the endpoints.
The config file contains the variables used to change the behavior of the app and stores other configuration like for example the id for Oauth
A brief description of each component in the api directory:
To display the info of all the teams or just a single team by id.
Calculate the total points of each user and update the prediction of each user before a match.
Contains controllers to view the result of matches, update results, get next match or n last matches.
Functions used by any of the other components. Mainly used to handle the connection to the database and queries. Speaking of that…
My second problem was to find a way to store the information of the teams, predictions, dates and results. Although most of the guides I found recommended a different approach (like non relational databases) I opted to use Postgres mainly because that’s what I usually do and didn’t want to add more difficulty as I was on a tight dead line with the first match starting on a couple days (procrastination, hooray!).
The database is simple and contains only four tables:
To create the API I used Express and its powerful router component. With it I can separate the routes the same way I created the structure and use the router to create the endpoint in each module:
// An example of matches.js inside api/matches// obtain routerconst express = require('express'),router = express.Router()...
// example of an endpoint.router.get("/all", (req, res) => {console.log("obtain all matches");// do stuff})
And in the server.js file I import all routes from the other modules:
// require express and import the routes in the api directoryconst express = require('express');matches = require('./api/matches'),teams = require('./api/teams'),users = require('./api/users'),...
// register the routes in the appapp.use('/teams',teams).use('/matches', matches).use('/users', users)... // other routes
To manage the database session and the queries I used Node-postgres. With this library you can obtain the database url from the environment (safer and used in some places like Heroku):
const { DATABASE_URL } = process.env;var pool = new Pool({connectionString: DATABASE_URL});
Or create the object and pass it to the Pool:
var pool = new Pool({user: 'username',host: 'localhost',database: 'database_name',password: 'my_password',port: 5432});
With the connections established you can execute queries like this:
// connect pool and query all teams in tablepool.connect().then(client => {return client.query("SELECT * FROM teams").then(data =>{// do stuff with the data...})
With this two components I was able to start coding the endpoints needed for each of the modules and store the data in the database
By the way if you think the code for the query is ugly… you are right! I was descending to hell … callback hell
But that’s a story for another day
If you want to test the app follow the next steps.
First clone the project from github:
git clone https://github.com/agmezr/quiniela.git
The project’s structure:
Install the dependencies of the project using npm:
npm install
Run the script in assets/database.sql to create the database:
psql <db name | postgres> -f assets/database.sql
After installing the dependencies and db, run the server using:
node server.js
If everything is ok you should see a message like this:
Staring app on 8080
Now open your browser (or use curl) and access localhost:8080/index to see an awesome response:
{"status":"ok"}
If you see that response everything is running. You can play with the other endpoints, for example to view the information of the first team enter to:
you will see this response:
[{"id":1,"name":"Russia","grp":"A"}]
On next articles I want to share my experience with the use of Oauth to login users using a Google account and creating the views to display the data user friendly and finally deploying it on Heroku.
As one of my fists approaches to Node I want to say it was very pleasant working with it. There are many guides helping the beginners including the official documentation and many more libraries to help you with common task like security, connection to db, etc. Of course there are some things that are hard to understand at first like Promises and the new ES6 syntax but nothing a few hours worth of coding can’t fix.
My advice if you want to try Node JS is create something easy and fun like I did and beware of callback hell!