loopback-example-relations
$ git clone https://github.com/strongloop/loopback-example-relations.git
$ cd loopback-example-relations
$ npm install
$ node .
In this example, we create a simple web app to demonstrate model relation concepts. The app consists of a single web page with a list of links to help us query and filter sample data via REST.
Prerequisites
Before starting this tutorial, you must install:
- Node.js
- LoopBack CLI tools; see lb
Tutorials
Knowledge
Procedure
Create the application
Application information
- Name:
loopback-example-relations - Directory to contain the project:
loopback-example-relations
$ lb app loopback-example-relations
... # follow the prompts
$ cd loopback-example-relations
Create the datasource
- Name:
transient - Connector:
other- Name:
transient
- Name:
$ lb datasource
... # follow the prompts, choose `other` to define custom connector
Create the models
Model information
- Name:
Customer- Data source:
db (memory) - Base class:
PersistedModel - Expose over REST:
Yes - Custom plural form: Leave blank
- Properties:
name- String
- Not Required
age- number
- Not Required
- Data source:
- Name:
Order- Data source:
db (memory) - Base class:
PersistedModel - Expose over REST:
Yes - Custom plural form: Leave blank
- Properties:
description- String
- Not Required
date- date
- Not Required
- Data source:
- Name:
Account- Data source:
db (memory) - Base class:
PersistedModel - Expose over REST:
No - Custom plural form: Leave blank
- Properties:
name- String
- Not Required
date- date
- Not Required
- Data source:
- Name:
Address- Data source:
transient - Base class:
Model - Expose over REST:
No - Custom plural form: Leave blank
- Properties:
street- String
- Not Required
city- String
- Not Required
state- String
- Not Required
zipCode- String
- Not Required
- Data source:
- Name:
Author- Data source:
db (memory) - Base class:
PersistedModel - Expose over REST:
No - Custom plural form: Leave blank
- Properties:
name- String
- Not Required
- Data source:
- Name:
Book- Data source:
db (memory) - Base class:
PersistedModel - Expose over REST:
Yes - Custom plural form: Leave blank
- Properties:
name- String
- Not Required
- Data source:
- Name:
EmailAddress- Data source:
transient - Base class:
PersistedModel - Expose over REST:
No - Custom plural form: Leave blank
- Properties:
label- String
- Not Required
address- String
- Not Required
- Data source:
- Name:
Link- Data source:
transient - Base class:
Model - Expose over REST:
No - Custom plural form: Leave blank
- Properties:
id- number
- Required
Please set
"id": truemanually for this property, like link.json
name- String
- Not Required
notes- String
- Not Required
- Data source:
- Name:
Reader- Data source:
db (memory) - Base class:
PersistedModel - Expose over REST:
No - Custom plural form: Leave blank
- Properties:
name- String
- Not Required
- Data source:
$ lb model Customer
... # follow the prompts, repeat for other models
Upper-case in model’s name would be interpreted as ‘-‘ in model’s file name, eg: EmailAddress has
email-address.json
Configure server-side views
LoopBack comes preconfigured with EJS out-of-box. This means we can use server-side templating by simply setting the proper view engine and a directory to store the views.
Create a views directory to store server-side templates.
$ mkdir server/views
Create index.ejs in the views directory.
Create account.ejs in the views directory.
Create email.ejs in the views directory.
Create address.ejs in the views directory.
Configure server.js to use server-side
templating. Remember to import the path package.
Replace root
Replace the default root.js with a new one which passes a given customer’s id to template engine.
Add sample data
Create six boot scripts:
sample-customers.jsz-book-people.jsz-customer-accounts.jsz-customer-address.jsz-customer-emails.js
We add z- in front of the boot script names to make sure they load last since LoopBack boot loads boot scripts alphabetically.
Create model relations
Model relation information
Customer- has many
Order- Property name for the relation:
orders - Custom foreign key:
customerId - Require a through model: No
- Property name for the relation:
-
Other Relations:(please add them manually)"address": { "type": "embedsOne", "model": "Address", "property": "billingAddress", "options": { "validate": true, "forceId": false } }, "emails": { "type": "embedsMany", "model": "EmailAddress", "property": "emailList", "options": { "validate": true, "forceId": false } }, "accounts": { "type": "referencesMany", "model": "Account", "property": "accountIds", "options": { "validate": true, "forceId": false } },
- has many
-
Book(please add them manually)"people": { "type": "embedsMany", "model": "Link", "scope": { "include": "linked" } } -
Link(please add them manually)"linked": { "type": "belongsTo", "polymorphic": { "idType": "number" }, "properties": { "name": "name" }, "options": { "invertProperties": true } } Order- belongs to
Customer- Property name for the relation: Leave blank - defaults to
customer - Custom foreign key: Leave blank
- Property name for the relation: Leave blank - defaults to
- belongs to
$ lb relation
? Select the model to create the relationship from:
...
> Customer
... # follow the prompts, repeat for other models
Some relations are not available in
lb, please add them inmodel-name.jsonmanually. LoopBack automatically derives relation and foreign key names when you leave the values empty.
Try the API
Start the application with node . and browse to [localhost:3000][localhost].
You should see various links. Each endpoint is defined as follows:
hasMany
- /api/customers
- List all customers
- /api/customers/4
- Look up a customer by ID
- /api/customers/youngFolks
- List a predefined scope named youngFolks
- /api/customers/4/orders
- List a given customer’s orders
- /api/customers?filter[include]=orders
- List all customers including their orders
- /api/customers?filter[include][orders]=customer
- List all customers including their orders which also include the customer
- /api/customers?filter[include][orders]=customer&filter[where][age]=21
- List all customers whose age is 21, including their orders
- /api/customers?filter[include][orders]=customer&filter[limit]=2
- List first two customers including their orders
- /api/customers?filter[include]=accounts&filter[include]=orders
- List all customers including their accounts and orders
embedsOne
- /api/customers/2/address
- List a given customer’s address
embedsMany
- /api/customers/3/emails
- List a given customer’s email
referencesMany
- api/customers/1/accounts
- List all accounts owned by a given customer
- /api/customers/1/accounts/1
- Look up a given accounts of a given customer by foreign key
- /api/customers/1/accounts/count
- Count accounts number of a given customer
polymorphic embedsMany
- /api/Books/1/people
- List the linked people of a given book
- /api/Books/1/people/1
- Look up the author of a given book by foreign key
- /api/Books/1/people/2
- Look up the reader of a given book by foreign key