Skip to content

Oh baby, work that lil Loopback in this Workshop! You can learn to "express" your "model" "relationships" right here!

Notifications You must be signed in to change notification settings

travezripley/node200-loopback-workshop

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

My Application

The project is generated by LoopBack.


Loopback Workshop


Overview


We are going to build out an API that will allow CRUD operations for Teams and Players, and query for players that belong to teams. This project is concerned with the back end, and doesn't need to have a front facing web app. The purpose of this workshop is to demonstrate how using a framework can make building and maintaining APIs easy.

Prerequisites


Install the Loopback CLI generator.

OS X and Linux

$ npm install -g loopback-cli

Windows

Follow these instructions

If you try to simply npm install -g strongloop without following these special instructions you will likely see a ton of errors.

Getting Started


Scaffold out the files for your new app using:

$ lb

Choose the arrow and enter keys to select the following options:

What's the name of your application?

  • node-200-loopback-workshop

Enter name of the directory to contain the project:

  • node-200-loopback-workshop

Which version of LoopBack would you like to use?

  • 3.x (current)

What kind of application do you have in mind?

  • api-server (A LoopBack API server with local User auth)

Initialize your repository

$ cd node200-loopback-workshop
$ git init

Add Test Script

There are already tests setup for you to ensure your project includes all the steps from this workshop. Add the following npm script to your package.json under scripts in the object, update it to have:

"scripts": {
  "test": "mocha test/*.spec.js"
}

Then add the test runner's dependencies with:

$ npm install --save-dev mocha chai chai-http

Authentication

Loopback has mechanisms to authenticate users, but we will want to disable this so that we will not have to log in (with a username and password) to work with our API. To disable authentication in a Loopback application you can comment out the enableAuth method in server/boot/authentication.js. Comment out the line below to turn authentication off.

// server.enableAuth();

Summary of Files Created


The main files that have been created include some that you should already be familiar with:

.editorconfig
.eslintignore
.eslintrc
README.md
.gitignore

And then a few that require a brief introduction to usage:

  • client/README.md - A simple document that is a placeholder that reminds you where to put your front end app.
  • server/boot/root.js - this is the first file Loopback will run. It is the entry point if you would like to trace applications code runs. It will boot up the server application.
  • server/middleware.development.json - this will be used to define/configure the middleware that should be used on each request.
  • server/middleware.json - this is an alternate file that will be used to configure the middleware when the application is running in production mode. You may want to turn off things like debug logs in production.
  • server/server.js - this contains the main server logic for the Express app and wires up the routing.
  • server/boot/authentication.js - this contains the authentication mechanisms, and can help secure access to endpoints.

Progress Check

You can run your application using:

$ node .

Then in your browser navigate to: http://localhost:3000

You will see a status message telling you the uptime of the application. Next, checkout the Swagger interface here: http://localhost:3000/explorer

The Loopback Explorer has already created a User model, and provided an interface that documents the api, and allows you to do some CRUD operations.

Friendly Warning

Currently, the application is using an in-memory database. Please note that every time you stop and start the app you will lose all the data that has been posted. Where Loopback really shines is in its ability to quickly connect to different datasources, so that you can swap out the storage mechanism, without having to change your code. You will find more detailed information about it in the DataSources section of this document.

Add a user

In the Loopback Explorer Click on User, and then click POST (/Users), then using the form in the UI add a new user as a JSON object in the value field:

{
  "realm": "example",
  "username": "mike",
  "email": "mike@example.com",
  "emailVerified": true
}

You don't need to add an id key/value, one will be created for you. You can also see an example by toggling the Model/Example link (under the Data Type column).

Next, click the Try it out! button. You should get a success message if you have entered a valid object (it must conform to the schema). If not check the response codes and error message(s) to fix your errors.

Then, once you have successfully added a user, click on the GET (/Users), and Try it out! to see if you can get all users. NOTE: if you did not turn off authentication you may get an error. See Authentication above.

Loopback has added this model based on the choices made at the CLI. Let's use the CLI to start building out the remaining data model we need for our API.

Adding Models


Models are used to define data objects for our API to store and retrieve. Here, we'll be adding two models: player and team.

Add a model using

$ lb model

...with the following options:

Select the data-source to attach player to:

  • db (memory)

Select model's base class

  • PersistedModel

Expose player via the REST API

  • Yes

Custom plural form

  • Press Enter and Accept Default

Common model or server only

  • Common

Then, enter the properties and types as follows:

Note: they do not need to be required or have default values

name: string
position: string
average: number

When you have added the last one hit enter at the name prompt and it will exit out of the CLI.

Use that same process to add a new model called team with the following schema:

name: string
city: string
market: number

Then, return to the Loopback Explorer and check out the new API endpoints you have created and have documented.

Insert Teams using the Explorer


Using the POST method in the Loopback Explorer create the following 3 teams:

{ name: "Braves", city: "Boston", market: 4000000 },
{ name: "Padres", city: "San Diego", market: 2000000 },
{ name: "Lakers", city: "Minnesota", market: 800000 }

Create Relationships


There are many types of relationships provided by Loopback. The most common is a one-to-many, which loopback calls a HasMany relationship. It is described this way, but it is also attainable by using BelongsTo or defining the many-to-one side. Review the documentation here to see more examples.

Let's add a relation between the teams and payers by using the following command in the CLI:

$ lb relation

Select the model to create the relationship from:

  • team

Relation type:

  • has many

Choose a model to create a relationship with:

  • player

Enter the property name for the relation:

  • Press Enter to accept the default players

Optionally enter a custom foreign key:

  • Press Enter to accept none

Require a through model?

  • No Enter through the remaining options to accept all defaults

Note: Through models are useful when you have a many-to-many relationships. Loopback has a HasManyThrough relation type that makes it simple to achieve many-to-many and expose the correct endpoints auto-magically.

Next, using the Loopback Explorer review the new API endpoints. You should now see that you can add players through a team endpoint http://localhost:3000/explorer/#!/team/team_prototype_create_players

Also look at the POST (/player) and note that the schema changed. Without any intervention on our end the Loopback CLI has added a teamId field for us. WOW!

Insert Players


Using the explorer use the team id to insert a few players onto any of the three teams:

name: "Larry Boggs",
position: "P",
average: 2.50
name: "Wade Rockerson",
position: "C",
average: 2.30
name: "Daryl Blueberry",
position: "LF",
average: 3.30

Now, use the GET (GET /teams/{id}/players) to query for all the players on one of the teams.

Next, try deleting a team that has players, what happens?

Remote Methods


The methods that Loopback creates for our CRUD operations are called Remote Methods, and you can choose to add additional handlers that are called when a model is accessed. You can also remove them from display/usage on the Explorer.

Registering remote Methods

If you look in your /common/models folder you will find that there is a .json file and a .js file for each model. The configuration is held as JSON, and the Javascript file is where you may write code that will execute when the model is interacted with. It's common to want to either manually add other types of operations (besides the CRUD operations) as endpoints. Or, there may also be a need to hook into an existing operation or trigger some other custom handlers to fire off via your API.

The CLI does a good job of providing much of what is needed, however here are a couple of scenario's where remote methods would come in handy:

  • if a new player is created, we needed to send an SMS message to the coach
  • if we needed the ability to use a custom endpoint /active to GET a count of all active players

In each case we would be needed to handle the business logic desired, and possibly generate a couple new endpoints, instead of relying upon only the ones generated by Loopback CLI. Review the Loopback docs here for more info here about Registering a Remote Method before moving on to the next section.

Removing remote Methods

You can remove Remote Methods inside each Model's /common/models/ Javascript file using the following syntax:

// inside the code block that is being exported
{MODEL_NAME}.disableRemoteMethod("delete", true);

That would remove the ability to use the DELETE method on that model.

DataSources


Quickly review the docs here for MongoDB connector and then let's add MongoDB as a datasource so that our application will persist data to a database. At the command line let's start adding a new datasource using:

$ lb datasource

Enter the data-source name:

  • MongoDB

Select the connector for MongoDB:

  • MongoDB (supported by StrongLoop)

All the other options

Enter through the remaining options to accept all defaults

Note: The last thing Loopback did for us was install the loopback-connector-mongodb package from npm (this is the system Loopback will use as a "plugin" and translate between Looback and the database driver)

Finally, we will need to update our models to use our new connector name: MongoDB in the model-config.json. Note that this is needed because we originally chose the option of in memory. Update it to replace db with MongoDB to match the new datasource.

"player": {
  "dataSource": "MongoDB",
  "public": true
},
"team": {
  "dataSource": "MongoDB",
  "public": true
}

Note: Once this is setup, be sure you have an instance of MongoDB running when your app starts or it will crash.

Now you should be able to stop and start the server, and the data should persist. Give it a try.

Another way to test it out is to add a new team using the Loopback Explorer, and then do a GET (/teams) look a the id Loopback creates by default. It should look like a MongoDB ObjectID ie. 59b9a3aa474ecd50f081578f

Configuring


By default we have mainly been assuming that development and production modes are the same, however in the real world, you may have separate databases, or configurations used when you run your app in production vs. in development. Another neat feature of Loopback is that it assumes file names will follow patterns. So for example if you want to setup a configuration to only apply when the environment is development you could add the contents of the JSON file to config.development.js like this:

module.exports = {
  "restApiRoot": "/api",
  "host": "0.0.0.0",
  "port": 3000
}

Loopback will look for this file, and use it (if it detects you are running in the default development mode). Then you could dynamically set the port, or host values like this:

{
  "restApiRoot": "/api",
  "host": process.env.HOST,
  "port": process.env.PORT
}

This will come in really handy if you deploy your application and need to set the port and host name dynamically. Be cautious, you may still need to keep a config.json file around, even though the settings will be overridden by either a config.development.js or config.production.js.

Configure DataSources

Notice that Loopback created a file for us called datasources.json. If you open the file, there should be two datasources listed, one for in memory storage called db and one that you created called MongoDB. This will work fine locally, but how about if you want to deploy your app to production?

You will need to create two files in the /server directory: datasources.local.js and datasources.production.js.

Move the contents of your datasources.json file to your datasources.local.js file and export them like this:

module.exports = {
  "db": {
    "name": "db",
    "connector": "memory"
  },
  "MongoDB": {
    "url": "mongodb://localhost:27017",
    "name": "MongoDB",
    "connector": "mongodb"
  }
}

Your datasources.json file should contain an empty object like this:

{}

You can leave your datasources.production.js file empty for now, we will need it when we deploy our applicaton to Heroku later in the lesson.

Note: you still need to keep a datasources.json file around, even though the settings will be overridden by either a datasources.local.js or datasources.production.js.

Middleware


Loopback makes it easy to add middleware without touching code. You add middleware modules in a two step process. First you need to install the package using npm, then you configure the middleware in a json object in server/middleware.json.

Add Morgan

Install Morgan using npm install --save-dev morgan

Add the following to server/middleware.json in the initial section of the JSON structure.

"morgan": {
   "params": ["dev", { "buffer": true } ]
 }

Serve Static

It is common to serve both your website and an API on the same server. Rather than have to make any special routes or use templates, the fastest way to do this with Loopback is to add middleware to serve up static content.

This does not even require adding a package, it simply requires setting up a configuration for middleware, and Loopback will wire up Express serve static for us.

Update the files part of the JSON structure in server/middleware.json to have the following value:

"files": {
  "loopback#static": {
    "params": "$!../client"
  }
}

The $!.. in this case, is Loopback syntax to map the root folder of the project. Now any files that you add to the client folder, will be served at the / path of your server.

Add a simple index.html page to the client folder so something will be displayed when users navigate to the base url.

Testing the project

Make sure MongoDB is running before you run the tests, but you do not need to run the server. Run the tests using:

$ npm run test

Deploy your app to Heroku

Using what you have learned in previous lessons:

  1. Upload your project to Github.
  2. Sync your project with CircleCI, so that every time you push to the master branch, CircleCI will run your tests.
  3. When the CircleCI tests are passing, it should automatically push a build to your Heroku application.
  4. Make sure you set your mongoDB enviroment variables inside of the settings. Open CirlceCI, and go to Settings in top right corner. Select Envirmonent Variables. Add new enviroment variable pointing to your mongdb_url in production.

Here are some helpful hints for deploying a Loopback app to Heroku with mongoDB:

  • You will need to create a configuration variable in Heroku to let Loopback know that it's running in a production environment. The Heroku dashboard makes it easy to add and remove config vars. Find your config vars and add this one: ENV=production.

  • Since we are using mongoDB as our database for this application, we need to have an instance of mongoDB running on our production server. We can accomplish this using the Heroku add-on for mLab. Find your add-ons through the Heroku dashboard, and add mLab. Make sure you provision a free (sandbox) plan.

Earlier in the lesson, you created a datasources.production.js file. Open it up and insert the following code:

module.exports = {
  "MongoDB": {
    "name": "MongoDB",
    "connector": "mongodb",
    "url": process.env.MONGODB_URI
  }
}

Note: the MONGODB_URI config variable was created auto-magically when we added mLab. Go look at your config vars in Heroku to see the magic!

Once you have made this change, push your project to the Github master branch, let CircleCI run your tests, and then it should automatically deploy to Heroku. Check out your Loopback API explorer at your-app-name.herokuapp.com/explorer.

Submit your work

Once all your tests are passing, and you have deployed your site to Heroku, you can Submit your project

Bonus

  • Add a simple page using React or EJS templates to display the players and teams

  • Write some tests for the back end

  • Add a remote method that hooks into the players model (use a remote method) and log a message when a new player is added to a team

About

Oh baby, work that lil Loopback in this Workshop! You can learn to "express" your "model" "relationships" right here!

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published