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": 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: 
- 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.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