Setting Up a Looback Application
I’m building a mobile app that calls a REST api from a NodeJS server. There are a number of frameworks to use:
I decided to use LoopBack based on what I read here. Setup is quite fast and it has a built in User model with authentication and authorization. This post describes the steps I took to do it.
Software versions I am using:
- OS X 10.10 on MacBook Pro (17-inch, Mid 2009)
- homebrew: 0.9.5
- mongodb: 2.6.5
- mysql: 5.6.21
- postgres: 9.3.5
- nvm: 0.17.3
- Node.js: 0.10.33
- npm: 1.4.28
- strongloop: 2.9.2
Initial Setup to create a LoopBack REST API project
Install Homebrew:
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Install mongodb:
brew install mongodb
Open a new terminal window and start mongodb:
mongod --config /usr/local/etc/mongod.conf
To exit mongodb, just push
CTRL-C
in the terminal window where you are running mongod.Optional - You can set launchd to start mongodb at login:
ln -sfv /usr/local/opt/mongodb/*.plist ~/Library/LaunchAgents
Optional - If you want to Load mongodb after setting launchd:
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mongodb.plist
Install mysql:
brew install mysql
To start mysql server, run:
mysql.server start
To stop mysql server, run:
mysql.server stop
To log into mysql, make sure mysql server is already running and then run:
mysql -uroot
Optional - To have launchd start mysql at login:
ln -sfv /usr/local/opt/mysql/*.plist ~/Library/LaunchAgents
Optional - If you set launchd for mysql, then to load mysql now:
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist
Install ossp-uuid for postgres:
brew instal ossp-uuid
Install postgres:
brew install postgres
To start postgres, open a new terminal window and run:
postgres -D /usr/local/var/postgres
To stop postgres, in the terminal window running postgres, push
CTRL-C
Optional - To have launchd start postgresql at login:
ln -sfv /usr/local/opt/postgresql/*.plist ~/Library/LaunchAgents
Optional - If you have set launchd for postgres, then to load postgresql now:
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
For my own convenience, I’ve also placed shortcuts in my .zshrc profile for starting and stopping mongodb, mysql, and postgres:
alias startmongo="mongod --config /usr/local/etc/mongod.conf" alias startmysql="mysql.server start" alias stopmysql="mysql.server stop" alias startpostgres="postgres -D /usr/local/var/postgres"
Install nvm:
curl https://raw.githubusercontent.com/creationix/nvm/v0.17.3/install.sh | bash
Install Node.js (this will install npm also):
nvm install 0.10
Set nvm’s default Node.js version to be used in any shell:
nvm alias default 0.10
Install StrongLoop command line client:
npm install -g strongloop
Create and go to a directory for your LoopBack app:
mkdir loopback-demo && cd loopback-demo
Create a loopback app:
slc loopback
Push the
Enter
key since LoopBack already knows you’re in theloopback-demo
directory. Here’s what you should see:[?] What's the name of your application? (loopback-demo)
Wait a few minutes and
slc loopback
to finish and you should see the following output:Your loopback-demo directory should look like:
drwxr-xr-x 10 jonxie staff 340 Nov 3 23:44 . drwx------+ 22 jonxie staff 748 Nov 4 12:34 .. -rw-r--r-- 1 jonxie staff 288 Oct 2 02:12 .editorconfig -rw-r--r-- 1 jonxie staff 24 Oct 2 02:12 .jshintignore -rw-r--r-- 1 jonxie staff 349 Oct 2 02:12 .jshintrc -rw-r--r-- 1 jonxie staff 120 Oct 2 02:12 .npmignore drwxr-xr-x 3 jonxie staff 102 Nov 3 23:44 client drwxr-xr-x 11 jonxie staff 374 Nov 3 23:44 node_modules -rw-r--r-- 1 jonxie staff 462 Nov 3 23:44 package.json drwxr-xr-x 7 jonxie staff 238 Nov 3 23:44 server
Create Models
NOTE: I followed this post by StrongLoop to create a model.
Now that you have a LoopBack project called loopback-demo
, it’s time to create a model called Person
.
Run this command:
slc loopback:model
[?] Enter the model name:
Enter
Person
for the model name and then choose db(memory) as your[?] Enter the model name: Person [?] Select the data-source to attach Person to: (Use arrow keys) (no data-source) ❯ db (memory)
Next LoopBack will ask you if you want to expose
Person
model as a REST API. ChooseYes
[?] Enter the model name: Person [?] Select the data-source to attach Person to: db (memory) [?] Expose Person via the REST API? (Y/n) Y
Next use
People
a custom plural form for the Person model for the REST API url[?] Enter the model name: Person [?] Select the data-source to attach Person to: db (memory) [?] Expose Person via the REST API? Yes [?] Custom plural form (used to build REST URL): People
Next LoopBack will ask you to name some properties for the Person model. Enter
name
for the first property.Let's add some Person properties now. Enter an empty property name when done. [?] Property name: name
Select
string
as the type for thename
property and then press the return key.Enter an empty property name when done. [?] Property name: name invoke loopback:property [?] Property type: (Use arrow keys) ❯ string number boolean object array date buffer (Move up and down to reveal more choices)
Next make the
name
property a required type since every person needs a name by typingy
and hit the return keyEnter an empty property name when done. [?] Property name: name invoke loopback:property [?] Property type: string [?] Required? (y/N) y
Now you should see the following output:
Enter an empty property name when done. [?] Property name: name invoke loopback:property [?] Property type: string [?] Required? Yes Let's add another Person property. Enter an empty property name when done. [?] Property name:
Repeat steps 1-8 for the following properties
age
as a required property of type stringdob
as a required propetty of type date
To exit out of creating a model, just hit the return key when you see the following text:
Let's add another Person property. Enter an empty property name when done. [?] Property name:
Run
ls -la
and you should see a directory structure similar as:drwxr-xr-x 11 jonxie staff 374 Nov 4 15:40 . drwx------+ 22 jonxie staff 748 Nov 4 12:34 .. -rw-r--r-- 1 jonxie staff 288 Oct 2 02:12 .editorconfig -rw-r--r-- 1 jonxie staff 24 Oct 2 02:12 .jshintignore -rw-r--r-- 1 jonxie staff 349 Oct 2 02:12 .jshintrc -rw-r--r-- 1 jonxie staff 120 Oct 2 02:12 .npmignore drwxr-xr-x 3 jonxie staff 102 Nov 3 23:44 client drwxr-xr-x 3 jonxie staff 102 Nov 4 15:40 common drwxr-xr-x 11 jonxie staff 374 Nov 3 23:44 node_modules -rw-r--r-- 1 jonxie staff 462 Nov 4 15:55 package.json drwxr-xr-x 7 jonxie staff 238 Nov 3 23:44 server
- server - Node application scripts and config files are here
- client - Javascript, HTML, CSS files for client
- common - Files common to both client and server
- models - Subdirectory of
common
folder, contains all model JSON and Javascript files
For more information about the project structure and files, click here.
Run the application:
slc run
Go to http://localhost:3000/explorer and follow StrongLoop’s instructions here to test the REST API for
POST
andGET
calls.
Connect REST API to a datasource
NOTE: I followed Strongloop’s Documentation here to add a datasource
Before you were using StrongLoop’s in-memory datasource to save data. Now it’s time to add a datasource such as MySQL or MongoDB
Run
slc loopback:datasource
to setup a datasource and enter inaccountDB
[?] Enter the data-source name: accountDB
Next you will be asked to choose a connector, choose
MySQL
and then hit the return key.[?] Enter the data-source name: accountDB [?] Select the connector for accountDB: other In-memory db (supported by StrongLoop) Email (supported by StrongLoop) ❯ MySQL (supported by StrongLoop) PostgreSQL (supported by StrongLoop) Oracle (supported by StrongLoop) Microsoft SQL (supported by StrongLoop) (Move up and down to reveal more choices)
After selecting
MySQL
you should see the following output on your terminal screen:[?] Enter the data-source name: accountDB [?] Select the connector for accountDB: MySQL (supported by StrongLoop)
Adding the mysql connector updates
server/datasource.json
to include theaccountDB
datasource you just added. The json file should look like:Create another model called
account
:slc loopback:model
[?] Enter the model name: account
Now choose
accountDB (mysql)
as the datasource for theaccount
model[?] Enter the model name: account [?] Select the data-source to attach account to: (no data-source) ❯ accountDB (mysql) db (memory)
Say
Yes
to exposing the REST API and type inaccounts
for the custom plural form[?] Expose account via the REST API? Yes [?] Custom plural form (used to build REST URL): accounts Let's add some account properties now.
Add the following properties which are all required
email
with type: stringlevel
with type: numbercreated
with type: datemodified
with type: date
Open
common/models/account.json
and it should look like:Install strongloops’s
loopback-connector-mysql
and add it to package.json:npm install loopback-connector-mysql --save
Your
package.json
should look like:Next you need to configure the datasource to use mysql running on your system. Edit
server/datasources.json
and after the line"connector": "mysql"
add the following:"host": "localhost", "port": 3306, "database": "loopbackDemo", "username": "loopback", "password": "loopback"
Your datasources.json file should now look like:
Now you need to setup your localhost’s mysql with a new user called
loopback
with proper privileges.If you haven’t done so yet, turn on mysql by running:
mysql.server start
Starting MySQL . SUCCESS!
Once you see that mysql server successful started, then log into mysql as the root user:
mysql --user=root mysql
While in the mysql prompt run the following commands:
The paragraphs below are taken and modified from: http://dev.mysql.com/doc/refman/5.6/en/adding-users.html
There are two user accounts with username
loopback
and a password ofloopback
. These are superuser accounts with full privileges. The'loopback'@'localhost'
account can be used only when connecting from localhost. The'loopback'@'%'
account uses the'%'
wildcard for the host part, so it can be used to connect from any host. It is necessary to have both accounts forloopback
to be able to connect from anywhere as monty. Without the localhost account, the anonymous-user account for localhost that is created by mysql_install_db would take precedence whenloopback
connects from localhost. As a result,loopback
would be treated as an anonymous user. The reason for this is that the anonymous-user account has a more specific Host column value than the'loopback'@'%'
account and thus comes earlier in the user table sort order.The ‘admin’@‘localhost’ account has no password. This account can be used only by admin to connect from the local host. It is granted the RELOAD and PROCESS administrative privileges. These privileges enable the admin user to execute the mysqladmin reload, mysqladmin refresh, and mysqladmin flush-xxx commands, as well as mysqladmin processlist. No privileges are granted for accessing any databases. You could add such privileges later by issuing other GRANT statements.
The ‘dummy’@‘localhost’ account has no password. This account can be used only to connect from the local host. No privileges are granted. It is assumed that you will grant specific privileges to the account later.
You should see the following output in your mysql prompt:
mysql> CREATE USER 'loopback'@'localhost' IDENTIFIED BY 'loopback'; Query OK, 0 rows affected (0.01 sec) mysql> GRANT ALL PRIVILEGES ON *.* TO 'loopback'@'localhost' WITH GRANT OPTION; Query OK, 0 rows affected (0.00 sec) mysql> CREATE USER 'loopback'@'%' IDENTIFIED BY 'loopback'; Query OK, 0 rows affected (0.00 sec) mysql> GRANT ALL PRIVILEGES ON *.* TO 'loopback'@'%' WITH GRANT OPTION; Query OK, 0 rows affected (0.00 sec) mysql> CREATE USER 'admin'@'localhost'; Query OK, 0 rows affected (0.00 sec) mysql> GRANT RELOAD,PROCESS ON *.* TO 'admin'@'localhost'; Query OK, 0 rows affected (0.00 sec) mysql> CREATE USER 'dummy'@'localhost'; Query OK, 0 rows affected (0.00 sec)
While you are still in the mysql prompt, create a database called loopbackDemo:
create database loopbackDemo
Now that you have your mysql database setup, it’s time to seed your database with LoopBack’s Node API. LoopBack’s sample file is at:
https://github.com/strongloop/loopback-example-mySimpleAPI/blob/master/server/create-test-data.js
The code is below:
Make sure to save this file to the
server
directory.From the root directory of your LoopBack project run:
node server/create-test-data.js
If all went well, you should see the following output:
Record created: { email: 'foo@bar.com', level: 10, created: Wed Nov 05 2014 23:41:07 GMT-0800 (PST), modified: Wed Nov 05 2014 23:41:07 GMT-0800 (PST), id: 1 } Record created: { email: 'bar@bar.com', level: 20, created: Wed Nov 05 2014 23:41:07 GMT-0800 (PST), modified: Wed Nov 05 2014 23:41:07 GMT-0800 (PST), id: 2 } done
Run
slc run
and then go to http://localhost:3000/api/accounts and you should see an XML or JSON response of the data you just created:<response> <result> <email>foo@bar.com</email> <level>10</level> <created>2014-11-06T07:41:07.000Z</created> <modified>2014-11-06T07:41:07.000Z</modified> <id>1</id> </result> <result> <email>bar@bar.com</email> <level>20</level> <created>2014-11-06T07:41:07.000Z</created> <modified>2014-11-06T07:41:07.000Z</modified> <id>2</id> </result> </response>
You can also go to http://localhost:3000/explorer/#!/accounts/account_find to see the JSON data you just created:
[ { "email": "foo@bar.com", "level": 10, "created": "2014-11-06T07:41:07.000Z", "modified": "2014-11-06T07:41:07.000Z", "id": 1 }, { "email": "bar@bar.com", "level": 20, "created": "2014-11-06T07:41:07.000Z", "modified": "2014-11-06T07:41:07.000Z", "id": 2 } ]
References
LoopBack
- http://strongloop.com/strongblog/compare-express-restify-hapi-loopback/
- http://docs.strongloop.com/display/SL/StrongLoop
- http://docs.strongloop.com/display/LB/Installing+StrongLoop
- http://docs.strongloop.com/display/LB/Create+a+simple+API