loopback-example-relations
⚠️ This LoopBack 3 example project is no longer maintained. Please refer to LoopBack 4 Examples instead. ⚠️
$ 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": true
manually 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:
- Name:
Shipment
- Data source:
db (memory)
- Base class:
PersistedModel
- Expose over REST:
No
- Custom plural form: Leave blank
- Properties:
date
- Date
- Not Required
description
- 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.js
z-book-people.js
z-customer-accounts.js
z-customer-address.js
z-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
- has many
Shipment
- Property name for the relation: Leave blank - defaults to
shipments
- Custom foreign key: Leave blank
- Property name for the relation: Leave blank - defaults to
- belongs to
Shipment
- belongs to
Order
- Property name for the relation: Leave blank - defaults to
order
- 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.json
manually. 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