All posts by Jonathan Lau

WebApp Scaffolding: Yeoman, AngularJS and more

Continuing from what we had yesterday, I was still exploring other options on what framework we could use. After exploring CakePHP a little more, I finally decided that it might not be that suitable for our project after all.

Jon and I also wanted to start out with some UI design first, so I thought I should quickly create a workflow for doing the layouts. We chose to use Bootstrap as our front-end UI framework. Having tried GruntJS and Bower before, I was thinking of how to best scaffold the application. That was when I found Yeoman.

Yeoman is a scaffolding tool that helps you get started on webapps. It has a community-maintained list of generators that scaffolds a new application by pulling in relevant Grunt tasks and Bower dependencies that you might need for your build.

Out of the 720 community-maintained generators for Yeoman, I decided to give the angular-fullstack generator a try. Besides being the most popular generator, it also seemed to fit our needs. This generator generates a webapp built on AngularJS and comes with an Express server. It also comes with useful build tools that simplify development.

Most of the day was spent figuring out how that app is scaffolded. The hardest part was figuring how everything worked together. After spending some time learning the basics of AngularJS, I tried to modify the app to authenticate with NUS OpenID. For that, I gave Passport another try.

Spent the next few hours trying to get that working. Passport uses what they call ‘strategies’ to log users in to different sites. I ended up writing one to connect to NUS OpenID based on code from another OpenID strategy. Although it was just a few lines of modification, it took me quite awhile to get it working. I also published this ‘strategy’ as an npm package (passport-nus-openid) so that the webbapp can use it as a dependency.

The last few hours of the day also helped me better understand the model-view-controller architecture that AngularJS is based on.

Although Jon and I stay at different ends of the island, Google Hangouts was really useful in helping us to work together. Using screen sharing and voice chat, it was almost as good as meeting up physically to work on the project.

Setting Up the Development Environment

Started off the day setting up all the servers needed to get started on the Orbital project.

Our initial thoughts were to use CakePHP as a framework for the webapp, so I started by installing Apache, PHP and MySQL on my development machine.  Configuring PHP to work properly with Apache on Windows was a little more challenging than getting it working on Linux. I ended up having to grab some packages from ApacheLounge in order to get both to work together.

Since we wanted to use a RESTful API to interface with the database, I thought of giving NodeJS a try. Got started with a node application running on the ExpressJS framework.

Read and learnt more about npm, and also how to define project dependencies in the package.json file.

When Jon set up a git repository on GitHub for this, I was also thinking of how to separate config settings such as database credentials from code that will be committed. Read previously that this is a good practice as different developers working on the code may have different config settings depending on the development environment. Started off with a separate JS file to hold the constants but later found a more elegant solution – the config package. This package handles configuration files very well. It reads configuration files from the /config folder and determines which values to provide to the app.

Since we wanted also to log users in though OpenID, I looked around to see if there was any packages for that. Initially found and tried to implement passport-openid but ran into some problems. Decided to give the openid package a try instead, and it worked out pretty well.

I also grabbed phpMyAdmin and started modelling the tables based on what Jon and I discussed yesterday. After much thought, I ended up with the following database schema.

CREATE TABLE IF NOT EXISTS `poll` (
`id` int(11) NOT NULL,
 `owner_id` int(11) NOT NULL,
 `question` text NOT NULL,
 `type` int(11) NOT NULL,
 `status` int(11) NOT NULL,
 `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
 `modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `poll_answers` (
`id` int(11) NOT NULL,
 `owner_id` int(11) NOT NULL,
 `question_id` int(11) NOT NULL,
 `answer` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `poll_meta` (
`id` int(11) NOT NULL,
 `poll_id` int(11) NOT NULL,
 `meta_key` varchar(255) NOT NULL,
 `meta_value` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `user` (
`id` int(11) NOT NULL,
 `openid` text NOT NULL,
 `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

ALTER TABLE `poll`
 ADD PRIMARY KEY (`id`);

ALTER TABLE `poll_answers`
 ADD PRIMARY KEY (`id`);

ALTER TABLE `poll_meta`
 ADD PRIMARY KEY (`id`);

ALTER TABLE `user`
 ADD PRIMARY KEY (`id`);

ALTER TABLE `poll`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `poll_answers`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `poll_meta`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `user`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

While doing that, I found out that MongoDB allowed you to store data as collections of documents, and you could easily nest data within each document. I decided to give MongoDB a try. While I did have some past experience with relational databases, MongoDB was fundamentally different as it was non-relational. Before today, I did have some idea of NoSQL databases though I have never tried one before. Spent a few moments exploring it on try.mongodb.org, a MongoDB shell within the web browser, before installing it on my local machine to further learn about it.

At the end of the day, I’m still not sure if MySQL or MongoDB would be more suitable for this project. Also, I’m still considering if separating UI from logic completely though a REST API would be a good choice. I’ll probably start working on the UI first before coming back to these decisions.