Please join our communication channels.
Mailing List at: https://groups.google.com/forum/#!forum/bodyapps
Gitter chat at: https://gitter.im/fashiontec/bodyapps
The software stack for our application includes following technologies:
Frontend: Backbone Framework
UI Design: Twitter BootStrap
We have used mongoose to access MongoDB database. Mongoose is a wrapper around MongoDB native library which is relatively easy to use rather than native MongoDB drivers.
Reason behind selecting this software stack
Why (Node.js + MongoDb) for server side rather than traditional PHP+MySql?
Let me share few advantages we had considered before coming to this decision:
Compared to traditional web-serving techniques where each connection (request) spawns a new thread, taking up system RAM and eventually maxing-out at the amount of RAM available, Node.js operates on a single-thread, using non-blocking I/O calls, allowing it to support tens of thousands of concurrent connections (held in the event loop).
One such calculation: assuming that each thread potentially has an accompanying 2 MB of memory with it, running on a system with 8 GB of RAM puts us at a theoretical maximum of 4000 concurrent connections, plus the cost of context-switching between threads. That’s the scenario we typically deal with in traditional web-serving techniques. By avoiding all that, Node.js achieves scalability levels of over pretty large number of concurrent connections (Upto 1M).
NPM: It is the official package manager for Node.js. It helps maintaining the complexity of project without much problem. In addition, it is easy for someone to create their own library/module and share it in npm registry. We can download any module from npm registry ,and use the module in our project without recreating the same stuff over and over again, which makes development pretty fast and clean in Node.js. It also makes the process of extending functionality of backend services simple, and a new contributor should find this functionality useful when starting with this project.
Also, there are many modules used in this project too :) and you can find the list here: package.json
Backbone's framework size is something around 60K and it's size is small compared to other options like AngularJS,EmberJS.
This file contains all features to be implemented during the summer 2015 ###Introduction BodyApps Service is a web based app which allows the user to take measurements and keep a track of all the measurements.Additionally the user can view the body in a 3D model which is customisable by the user. ###Issues
- User Interface is not intuitve and user friendly.
- The web app is not mobile first.So does not operate well with mobile users.
- There is no help provided on taking measurements which users did not like.
The plan of action this year will be to implement following features so that more people can use the webapp. As of now the webapp looks like this.
####Features to be implemented
- User Friendly Interaction Layer : The web app should be redesigned to be as user intutive as can be.
- Make it mobile first so that users don't have to log in through PC.
- Most importatnt is to provide help texts and animations for each measurement explaing to user how to take measurements.This is the main aim to increase the user base.
- Add social media sharing and activity option so that users can share their activity on different social media platforms.
- Login through Facebook and Twitter.Currently only Google is supported.
###Implementation of RealSense Intel RealSense is one of the latest technologies with perceptual computing which is going to own the future.Our aim in phase II of the development is to incorporate Intel RealSense with BodyApps.This is in higher priority than phase I.
####Technology Stack The BodyApps has three components :
- BodyApps Web Service
- BodyApps Android App
- BodyApps 3D Visualiser
- Front End : AngularJS with Bootstrap 3 on HTML5
- Back End : NodeJS with MongoDB
- Install Node.js, MongoDB on machine.
- Then run
npm installin project directory to install dependencies
Running the Server
- You will need a Google Account and create Google OAuth client credentials (see below)
- Some evironment variables need to be set to configure the system. Use your OSes native mechanism to set them to the correct values before starting the server:
|MONGODB_URI||URI of MongoDB to connect to, e.g. "mongodb://localhost/bodyapps-service"|
|SMTP_USER||GMail account to use for sending emails|
|GOOGLE_CLIENT_ID||Google client ID obtained from Google Developer Console|
|GOOGLE_CLIENT_SECRET||Matching client secret|
Declare one variable per var statement, it makes it easier to re-order the lines:
// Right var fs = require('fs'); var async = require('async'); // Wrong - hard to reorder lines var fs = require('fs'), async = require('async');
Naming: variables, properties and function names should:
lowerCamelCase, class names
- Be descriptive, avoid stuff like
- Single character variables & uncommon abbreviations should be avoided
app.js - is the central part of backend service. All important settings with express server are initialized here. For e.g. we use body-parser middleware for parsing request body as JSON.
server.js- sets appropriate port and starts the express server.
Gruntfile.js - is used to configure or define tasks and load Grunt plugins.
package.json - This file is used by npm to store metadata for projects published as npm modules.
logger.js - Logging setup is done using Winston.
app- It contains sub-folders like routes, models, lib, misc.
**routes** - all routes of User, Measurement, Image and Message API are defined.
**models** - all models for User, Measurement, Image and Message used by mongoose are defined.
**lib** - functions which are used in routes, but still independent in their functionality.
**misc** - miscellaneous functions. For example, currently it contains functions used in generation of HDF file from user and measurement record.
test - It contains the code related to testing of REST calls and some unit tests as well. It has two subfolders api and unit.
**api**- contains the code related to testing of all API’s like user, measurement, image and message.
**unit**- contains the unit tests of certain functions. Currently, functions like authCheck, serializeUser, deserializeUser of passport are unit tested using Sinon.
public - all static files (for e.g. html files) are kept in this folder. All static files are served wrt to this path by express server.
The system depends on some environment variables to operate correctly. Since actual production values for these variables cannot be added to the codebase, it is the system administrators job to provide them.
The mechanism of environment variables is simple and generic and works on any UNIX'ish platform w/o relying on a specific environment, runtime monitor, etc. Thus, it should work with PM2, upstart/monit, etc.
For a detailed list of possible environment variables, check out config.js
On a dedicated server, we can simply set the variables in file called
~/.bodyappsrc in the home folder of the user running the application. Assuming a user
bodyapps is used:
# /home/bodyapps/.bodyappsrc export MONGODB_URI='mongodb://localhost/bodyapps-service' export SMTP_USERfirstname.lastname@example.org' export SMTP_PASS='...' export GOOGLE_CLIENT_ID='...' export GOOGLE_CLIENT_SECRET='...' export LOG_LEVEL='debug'
Include the contents of this file by appending the following line to
To test, simply issue the following command. Output should be what has been set for
source ~/.profile echo $SMTP_USER > email@example.com
One of the most important part of our backend services are REST API calls. There are three main resources of our database and their corresponding API’s forms core part of backend:
In addition, we are using Message API for sending mails.
This is used for creating an user entity/resource in the database. The fields stored in user can be found here:User Model
_It returns a user whose object id(i.e. id) matches user_id.
It creates a new measurement record in the database. The fields stored in measurement record can be found here:Measurement Model.
It returns a measurement record whose m_id matches ‘measurement_id’ for header Accept: application/json.
For header, Accept: application/vnd.valentina.hdf, it returns a HDF record having details of user and it’s measurement record.
It returns the measurement record of a user whose user_id field equals the user_id mentioned in the URL.
It deletes the measurement record whose m_id matches the measurement_id of the URL.
It returns the list of deletedMeasurements for an user. It finds deleted measurement records whose user_id matches the one mentioned in URL.
It returns the list of measurements whose timestamp is greater than modifiedAfter value. Here modifiedAfter denotes number of milliseconds after 1st January, 1970 midnight.
It returns the list of measurements whose personName equals the one mentioned in URL and whose user_id matches user_id mentioned in URL.
Updates the fields passed in body of request for the measurement record whose m_id matches measurement_id in url.
POST /api/ API_VERSION/users/:user_id/measurements/:measurement_id/image/:side
It creates a new image for mentioned body part, and stores the appropriate entry in measurement record.
_It returns image whose object id(i.e. id) matches with image_id of URL.
It sends mail containing HDF file as an attachment.
Mocha: Test Runner
Supertest: Used for testing REST api.
Assert: For doing assertion check during the testing.