#bodyapps 项目的 Web 服务和 Web 应用程序组件
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:
Server: Node.js
Database: MongoDB
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.
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.
Backbone is extremely lightweight(as its only dependency is on one JavaScript library), it’s good for building fast and responsive applications and it’s most effective option if web applications are themselves small and single-page. And our web-app as per the plan was supposed to be one page application.
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
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
###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 :
Talking about the BodyApps Web Service it is developed in complete JavaScript using NodeJs for backend and BackboneJS for front-end.However this year we are going to refactor the frontend code to AngularJS.So to summarise :
npm install in project directory to install dependencies| Variable Name | Meaning |
|---|---|
| MONGODB_URI | URI of MongoDB to connect to, e.g. "mongodb://localhost/bodyapps-service" |
| SMTP_USER | GMail account to use for sending emails |
| SMTP_PASS | Matching password |
| GOOGLE_CLIENT_ID | Google client ID obtained from Google Developer Console |
| GOOGLE_CLIENT_SECRET | Matching client secret |
…
js // Right if (true) { console.log('winning'); }
// Wrong if (true) { console.log('losing'); }
Declare one variable per var statement, it makes it easier to re-order the lines:
```js
// Right
var fs = require('fs');
var async = require('async');
// Wrong - hard to reorder lines
var fs = require('fs'),
async = require('async');
…
bash
# /home/bodyapps/.bodyappsrc
export MONGODB_URI='mongodb://localhost/bodyapps-service'
export SMTP_USER='[email protected]'
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 ~/.profile:
source ~/.bodyappsrc
To test, simply issue the following command. Output should be what has been set for SMTP_USER:
source ~/.profile
echo $SMTP_USER
> [email protected]
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:
User API
Measurement API
Image API
In addition, we are using Message API for sending mails.
1.POST /api/API_VERSION/users
This is used for creating an user entity/resource in the database. The fields stored in user can be found here:User Model
2.GET /api/API_VERSION/users/:user_id
_It returns a user whose object id(i.e. id) matches user_id.
1.POST /api/API_VERSION/users/:user_id/measurements
It creates a new measurement record in the database. The fields stored in measurement record can be found here:Measurement Model.
2.GET /api/API_VERSION/users/:user_id/measurements/:measurement_id
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.
3.GET /api/API_VERSION/users/:user_id/measurements
It returns the measurement record of a user whose user_id field equals the user_id mentioned in the URL.
4.DELETE /api/API_VERSION/users/:user_id/measurements/:measurement_id
It deletes the measurement record whose m_id matches the measurement_id of the URL.
5.GET /api/API_VERSION/users/:user_id/deletedMeasurements
It returns the list of deletedMeasurements for an user. It finds deleted measurement records whose user_id matches the one mentioned in URL.
6.GET /api/API_VERSION/users/:user_id/measurements?modifiedAfter
It returns the list of measurements whose timestamp is greater than modifiedAfter value. Here modifiedAfter denotes number of milliseconds after 1st January, 1970 midnight.
7.GET /api/API_VERSION/users/:user_id/measurements?personName
It returns the list of measurements whose personName equals the one mentioned in URL and whose user_id matches user_id mentioned in URL.
8.PUT /api/API_VERSION/users/:user_id/measurements/:measurement_id
Updates the fields passed in body of request for the measurement record whose m_id matches measurement_id in url.
1.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.
2.GET /api/API_VERSION/images/:image_id
_It returns image whose object id(i.e. id) matches with image_id of URL.
1.POST /api/API_VERSION/message
It sends mail containing HDF file as an attachment.
1.POST /api/API_VERSION/users
2.GET /api/API_VERSION/users/:user_id
3.POST /api/API_VERSION/users/:user_id/measurements
4.GET /api/API_VERSION/users/:user_id/measurements/:measurement_id
5.POST /api/ API_VERSION/users/:user_id/measurements/:measurement_id/image/:side
6.GET /api/API_VERSION/images/:image_id
7.POST /api/API_VERSION/message
Mocha: Test Runner
Supertest: Used for testing REST api.
Assert: For doing assertion check during the testing.
暂无开放 Issues,或尚未同步最近议题。