All posts by Facundo Soria Guerrero

Exploring Loopback – Part 2.

Imagen-Devecoop-Loopback

Hi! In this new post we will add another model through code, see the relationships, and play a little with datasources.

In the previous post we created a todo model using the wizard.

Now we will create another model, category, this time manually. To do this we have many ways, we will see two of them:

  1. through code
  2. through a JSON schema

1 - Creating a model manually through code

As seen in the previous post, models are generally exstended from a base model (PersistedModel), so we have to do the following:

  1. Create a new file , for instance “create-category.js”, inside the boot (server/boot) folder, to have the model initialized when the application starts. You can copy the content from other files in that same folder. The files inside the “boot” folder are scripts to be executed in order when the application starts, and after the bootstrapper runs (https://github.com/strongloop/loopback-boot).

These scripts are usually used for configuration, models creation, and testing data creation.

Method 1 - using inheritance.

Adding these lines we create the model:

  var Model = server.loopback.Model;
  var Category = Model.extend('categories');

Here you can find the code.

Method 2 - using configurations.

The model can be created like this also:

  var config = {
      dataSource: 'db',
      public: true
    };
    server.model('Category', config);

Here you can find the code. Here you can see the configurations that can be applied.

Method 3 - using the createModel method:

var Category = server.loopback.createModel('Category');

Here you can find the code.

This one is the recommended way to create a model manually. To know more about createModel, we can read the apidocs.

I also include here this answer by Raymond Feng, co-founder of Loopback, if you want to know what he thinks about this different methods.

Now that we have our model created, when the server starts we will be able to use it creating a file “category.js” inside “common/models”, with this content:

module.exports = function(Category) {
  
};

We will see next what other things can be done inside this model, for now, leave it empty.

We will review another way of defining a model.

2 - Defining a model manually via JSON schema

To begin with, let’s add a “name” field.

Create “category.json” inside the common/models folder:

  {
    "name": "category",
    "plural": "categories",
    "base": "PersistedModel",
    "idInjection": true,
    "options": {
      "validateUpsert": true
    },
    "properties": {
      "name": {
        "type": "string",
        "required": true
      }
    },
    "validations": [],
    "relations": {},
    "acls": [],
    "methods": []
  }

Then create “category.js”, just like we did before.

Finally, we add this into “model-config.json”:

  "category": {
      "dataSource": "db",
      "public": true
    }

You can see this code here.

Validations

So we said that inside “category.js” we could do other things. What we do in this file is adding behaviour to the model, adding remote methods, hooks, bussiness logic, validations and more.

For now, let’s take a look at validations, and how LoopBack makes them really easy. Our model has a name, and we want it to be unique. To achieve this, let’s add in category.js the following:

  module.exports = function(Category) {
    Category.validatesUniquenessOf('name', {message: 'el nombre debe ser unico'});
  };

You can find the code here

As you can test, if we have an “Example” and we want to add another “Example”, the explorer will display:

Imagen-Duplicate

Validations is a long topic. For those interested, here’s a very good article about all the validation methods provided by the framework.

Relationships

So far, we haven’t gone too deep. Here’s when the interesting part begins.

With our new model, we want to categorize our ToDos, to group them, search, etc. Let’s say that a “todo” model can have zero, one or more categories. The todo model has a relationship with the model category.

We can define relationships in the JSON schema, for this example we’ll use hasAndBelongsToMany since a todo can have many categories, and a category can include many todos.

To add this relationship, we go to todo.json and add:

  "relations": {
    "categories": {
      "type": "hasAndBelongsToMany",
      "model": "category"
    }
  }

Here is the list of all possible relationships.

Let’s see an example:

Add some categories and todos first, like we did in the previous post.

  • I created 3 categories: House, Animals, Car

Imagen-GET-Categories

  • And I created 2 items: Clean bathroom, Buy food

Imagen-GET-Todo

And to add a category to an item, I send a PUT request to the endpoint /todos/{id}/categories/rel/{fk}. Here you can see all the HTTP methods.

Let’s add category “House” (fk: category id 1) to the item “Clean bathroom” (id: todo id 1):

Imagen-PUT-Categories-TODO

And we get:

Imagen-PUT-Categories-TODO-Response

To verify, make a GET request to /todos/{id}/categories

Imagen-GET-Categories-TODO

We can see we now have “House”

Imagen-GET-Categories-TODO-Response

Filters

Another great LoopBack feature is the different ways to query our data, in this post we will see the most common one, the “where” filter:

If we want to search the item with name “House”, we do this in the GET to categories:

Imagen-GET-Categories-TODO-Filter

We get all those that match “House” exactly. We can search the ones starting with “A”:

{"where" : {"name":{"like":"A"}}}

and we get “Animals”.

Imagen-GET-Categories-Filter-Like-Response

We can do this for all the models. Try yourself, how do you get the list of all the pending ToDos ?

We will see more on filters in the next part, when we integrate the client.

Persistance

Right now it’s all great, but we lose the data as soon as the server stops! We need to persist our data. LoopBack can connect to all the most popular databases. Let’s see how easy it is to connect to a noSQL database like MongoDB, and relational databases like MySQL.

Persistance with MongoDB

Let’s connect to my database of choice, MongoDB, through the CLI.

First of course we need Mongo installed, version 2.6 or higher, the downloads are here.

The we install the mongo connector, using npm:

  $ npm install loopback-connector-mongodb --save

And add our new datasource:

  $ slc loopback:datasource

We get the familiar wizard:

? Enter the data-source name: todoMongo
? Select the connector for todoMongo: 
  PostgreSQL (supported by StrongLoop) 
  Oracle (supported by StrongLoop) 
  Microsoft SQL (supported by StrongLoop) 
❯ MongoDB (supported by StrongLoop) 
  SOAP webservices (supported by StrongLoop) 
  REST services (supported by StrongLoop) 
  Neo4j (provided by community) 
(Move up and down to reveal more choices)

Let’s review the choices, they are self-descriptive:

  • ? Enter the data-source name: Name of the data source, any name you want, in this case, todoMongo
  • ? Select the connector for todoMongo: The connector name, in this case mongoDB, you can see it is supported by strongloop. There are many more to choose.

In datasources.json we will find the new one:

{
  "db": {
    "name": "db",
    "connector": "memory"
  },
  "todoMongo": {
    "name": "todoMongo",
    "connector": "mongodb"
  }
}

It’s all set. Before using the app, do the following:

  1. Configurate the connection:
  "todoMongo": {
    "name": "todoMongo",
    "connector": "mongodb",
    "host": "127.0.0.1", 
    "database": "todoDB", 
    "username": "", 
    "password": "", 
    "port": 27017 
  }

  1. Order the models to use the new datasource, changing the dataSource field in model-config.js, like this:
  "todo": {
    "dataSource": "todoMongo",
    "public": true
  },
  "category": {
    "dataSource": "todoMongo",
    "public": true
  }

Here you’ll find the code so far.

Go back to the explorer, add some categories. Now if you quit the server, start it again, and GET the categories, we will see they were persisted.

Persistance with MySQL

This works very similar as with Mongo.

Make sure you have MySQL 5.0 or higher, downloads are here.

Then follow the same steps as we did with Mongo: installing the connector, configuring models and connection, and that’s it.

Here you can find the connector documentation if needed.

That’s it for this part, I hope you enjoyed it, I sure did.

Next time we will integrate the client with our application.

Exploring Loopback – Part 1.

Imagen-Devecoop-Loopback

Hi, this is the first part of a series of articles related to the Loopback framework.

Loopback, as its pages says is a javascript framework based on express, so if you know express then it should be easy to understand and apply your knowledge.

LoopBack is an open source Node.js framework built on top of Express optimized for building APIs for mobile, web, and other devices. Connect to multiple data sources, write business logic in Node.js, glue on top of your existing services and data, connect using JS, iOS & Android SDKs

In my last project we choosed to use this powerful and interesting framework. Among the features we find:

  • Easy-to-use CLI wizard.
  • Built-in API Explorer.
  • Several features for creation, relationship and ACL on the models.
  • It’s isomorphic, sharing the same API between client and server side.

The best way to show you the potential is using it, so here we go…

Step 1 - Installation:

First we need to verify if we have Node and NPM installed, if you need help check this awesome post by Ale

Easy, we have a npm package, so run the following command:

$ npm install -g strongloop

(Yes, it says strongloop, that’s the company that develops loopback, it was recently acquired by IBM)

Once we have it installed, let’s get to work!

The first thing we need to do is creating a new project, as I’m someone that forgets the things that I have to do (and I have too much to do), I think that we can create something easy and productive: a TODO list.

How we do that ?, with our Easy-to-use CLI wizard:

$ slc loopback

In general the CLI wizard guides us asking questions, in this case we have the following (yes!, is a yeoman generator):

[?] Enter a directory name where to create the project: todo-app
[?] What's the name of your application? todo-app

Here we can see what we just did.

Step 2 - Creating our model

Our next step is creating our todo model, which is going to have a text field with string type and a boolean field to know if it is completed or not.

$ cd todo-app
$ slc loopback:model
? Enter the model name: todo
? Select the data-source to attach todo to: db (memory)
? Select model's base class: PersistedModel
? Expose todo via the REST API? Yes
? Custom plural form (used to build REST URL): todos
Let's add some todo properties now.

What we just chose ?:

  • Select the data-source to attach todo to: db (memory): Memory options means that when we stop the app, we will loose every saved data. On the next issues we will see how to use different datasources.
  • Select model’s base class: PersistedModel: PersistedModel is the base model of built-in models, except for Email. It provides all the standard create, read, update, and delete (CRUD) operations and exposes REST endpoints for them.
  • Expose todo via the REST API? Yes: We can use the API Explorer.

So far we created the model, now we need to add the properties that I mentioned:

Enter an empty property name when done.
? Property name: text
   invoke   loopback:property
? Property type: string
? Required? Yes
Let's add another todo property.
Enter an empty property name when done.
? Property name: completed
   invoke   loopback:property
? Property type: boolean
? Required? Yes

To finish we just use ctrl+c.

Two files were added, todo.js y todo.json. The todo.json file is where we define properties, fields, relationships, permissions, etc. And the todo.js file is where we gonna to create the remote methods, hooks and any related code of the model, etc.

This is our todo.json file:

{
  "name": "todo",
  "plural": "todos",
  "base": "PersistedModel",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {
    "text": {
      "type": "string",
      "required": true
    },
    "completed": {
      "type": "boolean",
      "required": true
    }
  },
  "validations": [],
  "relations": {},
  "acls": [],
  "methods": []
}

And todo.js:

module.exports = function(Todo) {

};

Additionally the new datasource of the model was added in the model-config.json file

Here we can see what we just did.

So, what we do next ?, how about running what we just did ?, we can run the app as the following:

$ node .
Browse your REST API at http://0.0.0.0:3000/explorer
Web server listening at: http://0.0.0.0:3000/

If we go to http://0.0.0.0:3000/explorer or http://localhost:3000/explorer we will see two models, todo and Users (the exposed models are the ones that have the public property set to true).

Well now is when you guys test the API (I will only show a couple of simple examples), loopback already create the API for us, where we have the most common operations: POST, GET, PUT, find, exists, etc.

####Adding a new item:

Fist we open the accordeon in POST /todos (http://localhost:3000/explorer/#!/todos/create)

We have three separated groups in there: Response Class, Parameters, Response Messages.

Response class has two visualizations options: Model: shows us how the properties are defined (type, required, not required, etc) and Model Schema: a json with default values.

In Parameters we have a textarea called value, in there we can add the item that we want (create the json by hand or click on the Model Schema on the Data Type column on the right to set as parameter value)

In both cases we can set the content type too.

At last, we have the Response Messages, which show us where the request from and some data of the response like the body, the code and the headers.

Imagen-Making-POST

In this example we add one item, “Clean the kitchen” :(. After we click on “Try it out!”, we have the following response:

Imagen-POST-RESPONSE

To see all added items we can do the same steps but with GET option, in addition we can use filter here, but we will leave this for later.

Imagen-GET

That was the first look on what Loopback offers, we create an API REST without adding a single line of code.

In the next part we will see how to integrate the client and connect with a database.