Let LoopBack Do It: A Walkthrough of the Node API Framework You've Been Dreaming Of

View all articles

It’s needless to mention the growing popularity of Node.js for application development. eBay has been running a production Node API service since 2011. PayPal is actively rebuilding their front-end in Node. Walmart’s mobile site has become the biggest Node application, traffic wise. On Thanksgiving weekend in 2014, Walmart servers processed 1.5 billion requests, 70 percent of which were delivered through mobile and powered by Node.js. On the development side, the Node package manager (npm) continues to grow rapidly, recently surpassing 150,000 hosted modules.

While Ruby has Rails and Python has Django, the dominant application development framework for Node has yet to be established. But, there is a powerful contender gaining steam: LoopBack, an open source API framework built by San Mateo, Calif., company StrongLoop. StrongLoop is an important contributor to the latest Node version, not to mention the current maintainers of Express, one of the most popular Node frameworks in existence.

IMAGE: loopback and node

Let’s take a closer look at LoopBack and it’s capabilities by turning everything into practice and building an example application.

What is LoopBack and How Does It Work with Node?

LoopBack is a framework for creating APIs and connecting them with backend data sources. Built on top of Express, it can take a data model definition and easily generate a fully functional end-to-end REST API that can be called by any client.

LoopBack comes with a built-in client, API Explorer. We’ll use this since it makes it easier to see the results of our work, and so that our example can focus on building the API itself.

You will of course need Node installed on your machine to follow along. Get it here. npm comes with it, so you can install the necessary packages easily. Let’s get started.

Create a Skeleton

Our application will manage people who would like to donate gifts, or things they just don’t need anymore, to somebody who might need them. So, the users will be Donors and Receivers. A Donor can create a new gift and see the list of gifts. A Receiver can see the list of gifts from all users, and can claim any that are unclaimed. Of course, we could build Donors and Receivers as separate roles on the same entity (User), but let’s try separating them so we can see how to build relations in LoopBack. The name of this groundbreaking application will be Givesomebody.

Install the StrongLoop command line tools through npm:

$ npm install -g strongloop

Then run LoopBack’s application generator:

$ slc loopback

     _-----_
    |       |    .--------------------------.
    |--(o)--|    |  Let's create a LoopBack |
   `---------´   |       application!       |
    ( _´U`_ )    '--------------------------'
    /___A___\    
     |  ~  |     
   __'.___.'__   
 ´   `  |° ´ Y ` 

? What's the name of your application? Givesomebody

Let’s add a model. Our first model will be called Gift. LoopBack will ask for the data source and base class. Since we haven’t set up the data source yet, we can put db (memory). The base class is an auto-generated model class, and we want to use PersistedModel in this case, as it already contains all the usual CRUD methods for us. Next, LoopBack asks if it should expose the model through REST (yes), and the name of the REST service. Press enter here to use the default, which is simply the plural of the model name (in our case, gifts).

$ slc loopback:model

? Enter the model name: Gift
? Select the data-source to attach Gift to: (Use arrow keys)
❯ db (memory)
? Select model's base class: (Use arrow keys)
  Model
❯ PersistedModel
? Expose Gift via the REST API? (Y/n) Yes
? Custom plural form (used to build REST URL):

Finally, we give the names of properties, their data types, and required/not-required flags. Gift will have name and description properties:

Let's add some Gift properties now.

Enter an empty property name when done.
? Property name: name
   invoke   loopback:property
? Property type: (Use arrow keys)
❯ string
? Required? (y/N)Yes

Enter an empty property name to indicate you are done defining properties.

The model generator will create two files which define the model in the application’s common/models: gift.json and gift.js. The JSON file specifies all metadata about the entity: properties, relations, validations, roles and method names. The JavaScript file is used to define additional behaviour, and to specify remote hooks to be called before or after certain operations (e.g., create, update, or delete).

The other two model entities will be our Donor and Receiver models. We can create them using the same process, except this time let’s put User as the base class. It will give us some properties like username, password, email out of the box. We can add just name and country, for example, to have a full entity. For the Receiver we want to add the delivery address, too.

Project Structure

Let’s have a look at the generated project structure:

IMAGE: Project Structure

The three main directories are: - /server – Contains node application scripts and configuration files. - /client – Contains .js, .html, .css, and all other static files. - /common – This folder is common to both the server and the client. Model files go here.

Here’s a detailed breakdown of the contents of each directory, taken from the LoopBack documentation:

File or directory Description How to access in code
Top-level application directory
package.json Standard npm package specification. See package.json N/A
/server directory - Node application files 
server.js Main application program file.  N/A
config.json Application settings. See config.json. app.get('setting-name')
datasources.json  Data source configuration file. See datasources.json. For an example, see Create new data source. app.datasources['datasource-name']
model-config.json Model configuration file. See model-config.json. For more information, see  Connecting models to data sources. N/A
middleware.json Middleware definition file. For more information, see Defining middleware. N/A
/boot directory Add scripts to perform initialization and setup. See boot scripts. Scripts are automatically executed in alphabetical order.
/client directory - client application files
README.md LoopBack generators create empty README file in markdown format. N/A
Other Add your HTML, CSS, client JavaScript files.  
/common directory - shared application files
/models directory Custom model files:
  • Model definition JSON files, by convention named model-name.json; for example customer.json.
  • Custom model scripts by convention named model-name.js; for example, customer.js.
For more information, see Model definition JSON file and Customizing models.
Node:
myModel = app.models.myModelName

Build Relationships

In our example, we have a few important relationships to model. A Donor can donate many Gifts, which gives the relation Donor has many Gift. A Receiver can also receive many Gifts, so we also have the relation Receiver has many Gift. On the other side, Gift belongs to Donor, and can also belong to Receiver if the Receiver chooses to accept it. Let’s put this into the language of LoopBack.

$ slc loopback:relation

? Select the model to create the relationship from: Donor
? Relation type: has many
? Choose a model to create a relationship with: Gift
? Enter the property name for the relation: gifts
? Optionally enter a custom foreign key:
? Require a through model? No

Note that there is no through model; we are just holding the reference to the Gift.

If we repeat the above procedure for Receiver, and add two belongs to relations to Gift, we will accomplish our model design on a back end side. LoopBack automatically updates the JSON files for the models to express exactly what we just did through theses simple dialogs:

// common/models/donor.json
  ...
  "relations": {
    "gifts": {
      "type": "hasMany",
      "model": "Gift",
      "foreignKey": ""
    }
  },
  ...

Add a Datasource

Now let’s see how to attach a real datasource to store all of our application data. For the purposes of this example, we will use MongoDB, but LoopBack has modules to connect with Oracle, MySQL, PostgreSQL, Redis and SQL Server.

First, install the connector:

$ npm install --save loopback-connector-mongodb

Then, add a datasource to your project:

$ slc loopback:datasource

? Enter the data-source name: givesomebody
? Select the connector for givesomebody: MongoDB (supported by StrongLoop)

The next step is to configure your datasource in server/datasources.json. Use this configuration for a local MongoDB server:

  ...
  "givesomebody": {
    "name": "givesomebody",
    "connector": "mongodb",
    "host": "localhost",
    "port": 27017,
    "database": "givesomebody",
    "username": "",
    "password": ""
  }
  ...

Finally, open server/model-config.json and change the datasource for all entities we want to persist in the database to "givesomebody".

{
  ...
  "User": {
    "dataSource": "givesomebody"
  },
  "AccessToken": {
    "dataSource": "givesomebody",
    "public": false
  },
  "ACL": {
    "dataSource": "givesomebody",
    "public": false
  },
  "RoleMapping": {
    "dataSource": "givesomebody",
    "public": false
  },
  "Role": {
    "dataSource": "givesomebody",
    "public": false
  },
  "Gift": {
    "dataSource": "givesomebody",
    "public": true
  },
  "Donor": {
    "dataSource": "givesomebody",
    "public": true
  },
  "Receiver": {
    "dataSource": "givesomebody",
    "public": true
  }
}

Testing Your REST API

It’s time to see what we’ve built so far! We’ll use the awesome built-in tool, API Explorer, which can be used as a client for the service we just created. Let’s try testing REST API calls.

In a separate window, start MongoDB with:

$ mongod

Run the application with:

$ node .

In your browser, go to http://localhost:3000/explorer/. You can see your entities with the list of operations available. Try adding one Donor with a POST /Donors call.

IMAGE: Testing Your API 2

IMAGE: Testing Your API 3

API Explorer is very intuitive; select any of the exposed methods, and the corresponding model schema will be displayed in the bottom right corner. In the data text area, it is possible to write a custom HTTP request. Once the request is filled in, click the “Try it out” button, and the server’s response will be displayed below.

IMAGE: Testing Your API 1

User Authentication

As mentioned above, one of the entities that comes pre-built with LoopBack is the User class. User possesses login and logout methods, and can be bound to an AccessToken entity which keeps the token of the specific user. In fact, a complete user authentication system is ready to go out of the box. If we try calling /Donors/login through API Explorer, here is the response we get:

{
  "id": "9Kvp4zc0rTrH7IMMeRGwTNc6IqNxpVfv7D17DEcHHsgcAf9Z36A3CnPpZJ1iGrMS",
  "ttl": 1209600,
  "created": "2015-05-26T01:24:41.561Z",
  "userId": ""
}

The id is actually the value of the AccessToken, generated and persisted in the database automatically. As you see here, it is possible to set an access token and use it for each subsequent request.

IMAGE: User Authentication

Remote Methods

A remote method is a static method of a model, exposed over a custom REST endpoint. Remote methods can be used to perform operations not provided by LoopBack’s standard model REST API.

Beside the CRUD methods that we get out of the box, we can add as many custom methods as we want. All of them should go into the [model].js file. In our case, let’s add a remote method to the Gift model to check if the gift is already reserved, and one to list all gifts that are not reserved.

First, let’s add an additional property to the model called reserved. Just add this to the properties in gift.json:

    ...
    "reserved": {
      "type": "boolean"
    }
    ...

The remote method in gift.js should look something like this:

module.exports = function(Gift) {

    // method which lists all free gifts
    Gift.listFree = function(cb) {
        Gift.find({
            fields: {
                reserved: false
            }
        }, cb);
    };

    // expose the above method through the REST
    Gift.remoteMethod('listFree', {
        returns: {
            arg: 'gifts',
            type: 'array'
        },
        http: {
            path: '/list-free',
            verb: 'get'
        }
    });

    // method to return if the gift is free
    Gift.isFree = function(id, cb) {
        var response;
        Gift.find({
            fields: {
                id: id
            }
        }, function(err, gift) {
            if (err) return cb(err);

            if (gift.reserved)
                response = 'Sorry, the gift is reserved';
            else
                response = 'Great, this gift can be yours';

        });
        cb(null, response);
    };

    // expose the method through REST
    Gift.remoteMethod('isFree', {
        accepts: {
            arg: 'id',
            type: 'number'
        },
        returns: {
            arg: 'response',
            type: 'string'
        },
        http: {
            path: '/free',
            verb: 'post'
        }
    });
};

So to find out if a particular gift is available, the client can now send a POST request to /api/Gifts/free, passing in the id of the gift in question.

Remote Hooks

Sometimes there is a need for execution of some method before or after the remote method. You can define two kinds of remote hooks:

  • beforeRemote() runs before the remote method.
  • afterRemote() runs after the remote method.

In both cases, you provide two arguments: a string that matches the remote method to which you want to “hook” your function, and the callback function. Much of the power of remote hooks is that the string can include wildcards, so it is triggered by any matching method.

In our case, let’s set a hook to print information to the console whenever a new Donor is created. To accomplish this, let’s add a “before create” hook in donor.js:

module.exports = function(Donor) {
    Donor.beforeRemote('create', function(context, donor, next) {
        console.log('Saving new donor with name: ', context.req.body.name);
    
        next();
    });
};

The request is called with the given context, and the next() callback in middleware (discussed below) is called after the hook runs.

Access Controls

LoopBack applications access data through models, so controlling access to data means defining restrictions on models; that is, specifying who or what can read and write the data or execute methods on the models. LoopBack access controls are determined by access control lists, or ACLs.

Let’s allow unlogged-in Donors and Receivers to view gifts, but only logged-in Donors to create and delete them.

$ slc loopback:acl

To begin, let’s deny everyone access to all endpoints.

? Select the model to apply the ACL entry to: Gift
? Select the ACL scope: All methods and properties
? Select the access type: All (match all types)
? Select the role: All users
? Select the permission to apply: Explicitly deny access

Next, allow everyone to read from Gift models:

$ slc loopback:acl

? Select the model to apply the ACL entry to: Gift
? Select the ACL scope: All methods and properties
? Select the access type: Read
? Select the role: All users
? Select the permission to apply: Explicitly grant access

Then, we want to allow authenticated users to create Gifts:

$ slc loopback:acl

? Select the model to apply the ACL entry to: Gift
? Select the ACL scope: A single method
? Enter the method name: create
? Select the role: Any authenticated user
? Select the permission to apply: Explicitly grant access

And finally, let’s allow the owner of the gift to make any changes:

$ slc loopback:acl

? Select the model to apply the ACL entry to: Gift
? Select the ACL scope: All methods and properties
? Select the access type: Write
? Select the role: The user owning the object
? Select the permission to apply: Explicitly grant access

Now when we review gift.json, everything should be in place:

"acls": [
  {
    "accessType": "*",
    "principalType": "ROLE",
    "principalId": "$everyone",
    "permission": "DENY"
  },
  {
    "accessType": "READ",
    "principalType": "ROLE",
    "principalId": "$everyone",
    "permission": "ALLOW"
  },
  {
    "accessType": "EXECUTE",
    "principalType": "ROLE",
    "principalId": "$authenticated",
    "permission": "ALLOW",
    "property": "create"
  }
],

One important note here: $authenticated is a predefined role which corresponds to all users in the system (both Donors and Receivers), but we only want to allow Donors to create new Gifts. Therefore, we need a custom role. As Role is one more entity we get out of the box, we can leverage its API call to create the $authenticatedDonor role in the boot function, and then just modify pricipalId in gift.json.

It will be necessary to create a new file, server/boot/script.js, and add the following code:

Role.create({
    name: 'authenticatedDonor'
}, function(err, role) {
    if (err) return debug(err);
})

The RoleMapping entity maps Roles to Users. Be sure that Role and RoleMapping are both exposed through REST. In server/model-config.json, check that "public" is set to true for the Role entity. Then in donor.js, we can write a “before create” hook that will map the userID and roleID in the RoleMapping POST API call.

Middleware

Middleware contains functions that are executed when a request is made to the REST endpoint. As LoopBack is based on Express, it uses Express middleware with one additional concept, called “middleware phases.” Phases are used to clearly define the order in which functions in middleware are called.

Here is the list of predefined phases, as provided in the LoopBack docs:

  1. initial - The first point at which middleware can run.
  2. session - Prepare the session object.
  3. auth - Handle authentication and authorization.
  4. parse - Parse the request body.
  5. routes - HTTP routes implementing your application logic. Middleware registered via the Express API app.use, app.route, app.get (and other HTTP verbs) runs at the beginning of this phase. Use this phase also for sub-apps like loopback/server/middleware/rest or loopback-explorer.
  6. files - Serve static assets (requests are hitting the file system here).
  7. final - Deal with errors and requests for unknown URLs.

Each phase has three subphases. For example, the subphases of the initial phase are:

  1. initial:before
  2. initial
  3. initial:after

Let’s take a quick look on our default middleware.json:

{
  "initial:before": {
    "loopback#favicon": {}
  },
  "initial": {
    "compression": {},
    "cors": {
      "params": {
        "origin": true,
        "credentials": true,
        "maxAge": 86400
      }
    }
  },
  "session": {
  },
  "auth": {
  },
  "parse": {
  },
  "routes": {
  },
  "files": {
  },
  "final": {
    "loopback#urlNotFound": {}
  },
  "final:after": {
    "errorhandler": {}
  }
}

In the initial phase, we call loopback.favicon() (loopback#favicon is the middleware id for that call). Then, third-party npm modules compression and cors are called (with or without parameters). In the final phase, we have two more calls. urlNotFound is a LoopBack call, and errorhandler is third-party module. This example should demonstrate that a lot of built in calls can be used just like the external npm modules. And of course, we can always create our own middleware and call them through this JSON file.

loopback-boot

To wrap up, let’s mention a module which exports the boot() function that initializes the application. In server/server.js you’ll find the following piece of code, which bootstraps the application:

boot(app, __dirname, function(err) {
    if (err) throw err;
  
    // start the server if `$ node server.js`
    if (require.main === module)
        app.start();
});

This script will search the server/boot folder, and load all the scripts it finds there in alphabetical order. Thus, in server/boot, we can specify any script which should be run at start. One example is explorer.js, which runs API Explorer, the client we used for testing our API.

Got the repetition blues? Don't build that Node API from scratch again. Let LoopBack do it!

Conclusion

Before I leave you, I would like to mention StrongLoop Arc, a graphical UI that can be used as an alternative to slc command line tools. It also includes tools for building, profiling and monitoring Node applications. For those who are not fans of the command line, this is definitely worth trying.

IMAGE: Conclusion

Generally speaking, LoopBack can save you a lot of manual work since you are getting a lot of stuff out of the box. It allows you to focus on application-specific problems and business logic. If your application is based on CRUD operations and manipulating predefined entities, if you are sick of rewriting the user’s authentication and authorization infrastructure when tons of developers have written that before you, or if you want to leverage all the advantages of a great web framework like Express, then building your REST API with LoopBack can make your dreams come true. It’s a piece of cake!

About the author

Jovan Jovanovic, Serbia
member since July 23, 2014
Jovan is an entrepreneur and engineer with a strong mathematical background. He doesn't care about the technology but cares about the problem that the technology can solve. [click to continue...]
Hiring? Meet the Top 10 Freelance Node.js Developers for Hire in December 2016

Comments

Abdul Aleem
very informative thanks for sharing..
Evan Wieland
Yes, very good read! Love the .gif too!
John
would not recommend using loopback, at least not in the long term. its ORM is not very mature and is lacking many features and the framework itself is not very well maintained by the authors/community. there is a huge backlog of pull requests and from our experience their updates usually introduce breaking changes without notice
Luke Bell
I'm sorry John, but I totally disagree with you, maybe it's your experience but we are using Loopback since version 1 and now have migrated to version 2. We are supporting 5000 requests per second and we had no performance problems and the ORM it's as mature or even more as Waterline , Sequelize or JugglingDB. Of course from one version to another errors may appear but Strongloop has a large community giving support. Node community tries through pull request to help to improve the modules that we use, if you do not believe that, then you should try C#. Did you try Sails With Waterline? Believe me, you do not know what a module not very well maintained is.
martinkrcho
I've been considering Loopback for an application with AngularJS, Android and iOS clients for a while now. This article is a very nice addition to the original documentation. I would really appreciate an article dedicated to using the SDKs for the UI clients mentioned above. :)
michalstanko
"StrongLoop is an important contributor to the latest Node version, and they’re the same guys that brought us Express" Forgive me if I'm wrong, but wasn't it TJ Holowaychuk who brought us Express, and StrongLoop now only continues developing it after he abandoned it?
Olivier
Great read. after reading the strongloop docs and cut my hair with user/roles, i could say than it is quickly to start a project but very slowly to continue. perhaps python/django gave me all so easy than now i head hache with strongloop. Realy interesting but not yet enougth mature i think. Thanks
Bulkan Evcimen
> and they’re the same guys that brought us Express, one of the most popular web frameworks for Node. This statement is incorrect. TJ Holowaychuk was the initial creator of express and when he left the Node community the express project was transferred to Strongloop. Here [1] is the oldest/first commit on the package.json file 1 - https://github.com/strongloop/express/commit/903c2aa642616fc7f39cd5c1d97d2cde4185ce4b#diff-b9cfc7f2cdf78a7f4b91a753d10865a2
Safoor Safdar
Well, very good. Look forward to simple application implementation like "todo" with loopback just for tutorial purposes.
Jovan Jovanovic
Good point, next iteration will go in depth more with Angular SDK probably.
Richard
Indeed - this is a good read ... http://hueniverse.com/2014/07/30/open-source-dickishness/
Richard
As http://hueniverse.com/2014/07/30/open-source-dickishness/ points out, the core team who had been working on it had their access cut off
Rodrigo Pandini
I also think so.
Jovan Jovanovic
Right, the sentence is not properly designed.
alex mejias
any one know where I can find the source for this project?
Olivier
Interesting ...
André Simões
Good job. Thanks. There's a typo in the article.. when you run the generator: $ lc loopback -> $ slc loopback
Tim
Thanks for the article - very informative. After installing StrongLoop, you say to run the LoopBack's application generator using the command "lc loopback". Shouldn't the command be "slc loopback"?
Melvis Yadel Perez Bautista
I already use loopback with angularjs, its not so hard to implemen, go to the strongloop docs :)
Wolfgang Becker
I think the listFree function was intended to use a 'where' filter instead of 'fields'
Jovan Jovanovic
Sorry, the typo. Will be corrected.
Nick McCrea
Thanks for pointing this out, Tim! You are correct, and the typo has been fixed.
Nick McCrea
Thanks Andre! This has been corrected.
Nick McCrea
Thanks for catching this, Bulkan! This sentence has been corrected.
Nick McCrea
Good catch! This sentence has been rephrased to fix the error.
Richard
Take a look at http://cleverstack.io/documentation/backend/ - it should prove quick to start and quick and easy to develop :)
Olivier
Thanks Richard very interesting !!! I m definitivily angry with loopback, two weeks working on and discovered an awfull relationnal bug on RoleMapping with mongodb connector ... My project is down and my time lost. May i contact you ? Because i just follw your getting started and got an npm error, so i can t start. Thanks
Richard
Sure thing, contact me on twitter @pilsy
Khaled Debeky
help please! i tried to the example using my mysql DB, i used "arc" to migrate my model. but it seems that the built in model "acl" was not migrated. as i get the below error when trying to add a new "Donor" is that a bug i should report, or i did something wrong { "error": { "name": "Error", "status": 500, "message": "ER_NO_SUCH_TABLE: Table 'test.acl' doesn't exist", "code": "ER_NO_SUCH_TABLE", "errno": 1146, "sqlState": "42S02", "index": 0, "stack": "Error: ER_NO_SUCH_TABLE: Table 'test.acl' doesn't exist\n at Query.Sequence._packetToError (c:\\Workspace\\Node\\Givesomebody\\node_modules\\loopback-connector-mysql\\node_modules\\mysql\\lib\\protocol\\sequences\\Sequence.js:48:14)\n at Query.ErrorPacket (c:\\Workspace\\Node\\Givesomebody\\node_modules\\loopback-connector-mysql\\node_modules\\mysql\\lib\\protocol\\sequences\\Query.js:83:18)\n at Protocol._parsePacket (c:\\Workspace\\Node\\Givesomebody\\node_modules\\loopback-connector-mysql\\node_modules\\mysql\\lib\\protocol\\Protocol.js:271:23)\n at Parser.write (c:\\Workspace\\Node\\Givesomebody\\node_modules\\loopback-connector-mysql\\node_modules\\mysql\\lib\\protocol\\Parser.js:77:12)\n at Protocol.write (c:\\Workspace\\Node\\Givesomebody\\node_modules\\loopback-connector-mysql\\node_modules\\mysql\\lib\\protocol\\Protocol.js:39:16)\n at Socket.<anonymous> (c:\\Workspace\\Node\\Givesomebody\\node_modules\\loopback-connector-mysql\\node_modules\\mysql\\lib\\Connection.js:96:28)\n at Socket.emit (events.js:107:17)\n at readableAddChunk (_stream_readable.js:163:16)\n at Socket.Readable.push (_stream_readable.js:126:10)\n at TCP.onread (net.js:538:20)\n --------------------\n at Protocol._enqueue (c:\\Workspace\\Node\\Givesomebody\\node_modules\\loopback-connector-mysql\\node_modules\\mysql\\lib\\protocol\\Protocol.js:135:48)\n at PoolConnection.query (c:\\Workspace\\Node\\Givesomebody\\node_modules\\loopback-connector-mysql\\node_modules\\mysql\\lib\\Connection.js:201:25)\n at runQuery (c:\\Workspace\\Node\\Givesomebody\\node_modules\\loopback-connector-mysql\\lib\\mysql.js:146:16)\n at executeWithConnection (c:\\Workspace\\Node\\Givesomebody\\node_modules\\loopback-connector-mysql\\lib\\mysql.js:188:7)\n at Ping.onPing (c:\\Workspace\\Node\\Givesomebody\\node_modules\\loopback-connector-mysql\\node_modules\\mysql\\lib\\Pool.js:94:5)\n at Ping.<anonymous> (c:\\Workspace\\Node\\Givesomebody\\node_modules\\loopback\\node_modules\\continuation-local-storage\\context.js:74:17)\n at bound (domain.js:254:14)\n at Ping.runBound [as _callback] (domain.js:267:12)\n at Ping.Sequence.end (c:\\Workspace\\Node\\Givesomebody\\node_modules\\loopback-connector-mysql\\node_modules\\mysql\\lib\\protocol\\sequences\\Sequence.js:96:24)\n at Ping.Sequence.OkPacket (c:\\Workspace\\Node\\Givesomebody\\node_modules\\loopback-connector-mysql\\node_modules\\mysql\\lib\\protocol\\sequences\\Sequence.js:105:8)" } }
mountain dew
I want to develop a non-database custom connector say REST from scratch. The documentation talks more about the database conenctor. Is there any article on this. Any pointers will help.
Ritesh Jagga
I am new to loopback so this might be a silly issue. When I restarted the server (node .) after creating script.js file to create authenticatedDonor role, I get the following error: ReferenceError: Role is not defined. In model-config.json file, Role's public property is set to true. Google search and Loopback Google group don't return anything relevant for this error.
Ritesh Jagga
Solved it like this: In the script.js file, module.exports = function (app) { var role = app.models.Role; role.create({ ... }); }
Richard
I haven't heard from you, but if your still having issues then take a look at http://cleverstack.io/blog/guides/getting-started-with-cleverstack/
Richard
Here's a better quick look (and introduction) to CleverStack - https://www.youtube.com/watch?v=M1cUtt7aYRg&list=PL3-XzBZL4kNHql6Iwa3jScw-5Jpnom63Y
ankur1ankur
Hey Jovan, thanks for such a nice article. Knowing that post request to /gifts with donorId in payload will create the gift. Just wondering if it can be done by making POST to the following route: /donors/5609075a4d6d050853498214/gifts?access_token=....... It doesn't won't add the gift but return 401. Do I need to make any changes to ACL to get it working, is there any built in method to post to gifts like this??
Vasanth
Finally! a proper loopback 'get started' blog. Thank you
Shakeel Syed
Sorry! I am new to StrongLoop. For login, why do we call /Donors/login instead of /Users/login
Gavin
nice framework to quickly try some ideas.
Ye Joo Park
Wonderful article, thanks!!!
Olivier
Very bad expériences with loopback, doc is out date and lots things are buggy. I hatte Nodejs, using loopback définitively put me off all is around nodejs. Perhaps in 10 years I ll give it a try but for the moment I ve lost more of time than I win. Nodejs is for me à joke.
Eduardo
hi, how are you ? I need do, e method manually, It must to connect to mySQL, how can I do this ? regards Eduardo
sudhir baru
Hi, This article uses mongodb. So the tables are created dynamically. But in psql or sql based we have to create table ourself. there is also concept ds.automigrate which creates the tables for us.
Akash
One place for learning it all to start with loopback. Thanks @disqus_AEHf73Yuw7:disqus :)
kevin soundgraphia
How to host loopback project in windows server for production?
comments powered by Disqus
Subscribe
The #1 Blog for Engineers
Get the latest content first.
No spam. Just great engineering and design posts.
The #1 Blog for Engineers
Get the latest content first.
Thank you for subscribing!
You can edit your subscription preferences here.
Trending articles
Relevant technologies
About the author
Jovan Jovanovic
Java Developer
Jovan is an entrepreneur and engineer with a strong mathematical background. He doesn't care about the technology but cares about the problem that the technology can solve.