API – Expanding Objects

Introduction

This article will explain how to use the $expand attribute to pull the information of linked entities without making a separate request.

At various times in using the API, it will return URL references to various objects instead of the actual object data itself. Such requests occur most often when getting entity information. Below is such a request, with it’s associated response.

GET https://loanpro.simnang.com/api/public/api/1/odata.svc/Loans

The response to this request should be similar to the one below.

{
"d": {
"results": [
{
"__metadata": {
"uri": "https://loanpro.simnang.com/api/public/api/1/odata.svc/Loans(id=2)",
"type": "Entity.Loan"
},
"Insurance": {
"__deferred": {
"uri": "Loans(id=2)/Insurance"
}
},
"CustomFieldValues": {
"__deferred": {
"uri": "Loans(id=2)/CustomFieldValues"
}
},
"ChecklistItemValues": {
"__deferred": {
"uri": "Loans(id=2)/ChecklistItemValues"
}
},
"Documents": {
"__deferred": {
"uri": "Loans(id=2)/Documents"
}
},
"Collateral": {
"__deferred": {
"uri": "Loans(id=2)/Collateral"
}
},
...
"id": 2,
"displayId": "44449817",
"title": "44449817",
"settingsId": 2,
"setupId": 2,
"insurancePolicyId": "0",
"collateralId": 2,
"linkedLoan": null,
"modId": null,
"modTotal": 0,
"humanActivityDate": "/Date(1463011200)/",
"created": "/Date(1459370262)/",
"active": 1,
"archived": 0,
"loanAlert": null,
"temporaryAccount": 0,
"deleted": 0,
"deletedAt": null,
"_relatedMetadata": null,
"_dynamicProperties": null
}]
}
}

As you can see, much of the associated entities only have URIs returned. This means that to get the collateral information for the loan, we would have to send the following request.

GET https://loanpro.simnang.com/api/public/api/1/odata.svc/Loans(id=2)/Collateral

However, that means we would have to send many requests to get all of the information for a single loan. Imagine how hard it would be to get all of the loan information for every loan for a company!

Luckily, the OData Protocol specifies an $expand attribute which allows us to pull information of linked entities without making a separate request.

Using Expand

The $expand attribute acts as a GET parameter at the end of a URL and tells the API what entities to expand. This means that you only pull the information you need from the server, which saves on bandwidth and decreases the time it takes to make a request. Below is an example on how to get the collateral information of loan #2 using the expand attribute.

GET https://loanpro.simnang.com/api/public/api/1/odata.svc/Loans(id=2)?$expand=Collateral

The response should be similar to the one shown below.

{
"d": {
"__metadata": {
"uri": "https://loanpro.simnang.com/api/public/api/1/odata.svc/Loans(id=2)",
"type": "Entity.Loan"
},
"Insurance": {
"__deferred": {
"uri": "Loans(id=2)/Insurance"
}
},
"CustomFieldValues": {
"__deferred": {
"uri": "Loans(id=2)/CustomFieldValues"
}
},
"ChecklistItemValues": {
"__deferred": {
"uri": "Loans(id=2)/ChecklistItemValues"
}
},
"Documents": {
"__deferred": {
"uri": "Loans(id=2)/Documents"
}
},
"Collateral": {
"__metadata": {
"uri": "https://loanpro.simnang.com/api/public/api/1/odata.svc/Collateral(id=2)",
"type": "Entity.Collateral"
},
"Loan": {
"__deferred": {
"uri": "Collateral(id=2)/Loan"
}
},
"CustomFieldValues": {
"__deferred": {
"uri": "Collateral(id=2)/CustomFieldValues"
}
},
"id": 2,
"loanId": 2,
"a": null,
"b": null,
"c": null,
"d": null,
"additional": null,
"collateralType": "collateral.type.other",
"vin": null,
"distance": null,
"bookValue": null,
"color": null,
"gpsStatus": null,
"gpsCode": null,
"licensePlate": null,
"gap": null,
"warranty": null
},
"LoanSettings": {
"__deferred": {
"uri": "Loans(id=2)/LoanSettings"
}
},
"LoanSetup": {
"__deferred": {
"uri": "Loans(id=2)/LoanSetup"
}
},
"Notes": {
"__deferred": {
"uri": "Loans(id=2)/Notes"
}
},
"Promises": {
"__deferred": {
"uri": "Loans(id=2)/Promises"
}
},
"Charges": {
"__deferred": {
"uri": "Loans(id=2)/Charges"
}
},
"Payments": {
"__deferred": {
"uri": "Loans(id=2)/Payments"
}
},
"LoanFunding": {
"__deferred": {
"uri": "Loans(id=2)/LoanFunding"
}
},
"Advancements": {
"__deferred": {
"uri": "Loans(id=2)/Advancements"
}
},
"Credits": {
"__deferred": {
"uri": "Loans(id=2)/Credits"
}
},
"DueDateChanges": {
"__deferred": {
"uri": "Loans(id=2)/DueDateChanges"
}
},
"CurtailmentDates": {
"__deferred": {
"uri": "Loans(id=2)/CurtailmentDates"
}
},
"StatusArchive": {
"__deferred": {
"uri": "Loans(id=2)/StatusArchive"
}
},
...
"id": 2,
"displayId": "44449817",
"title": "44449817",
"settingsId": 2,
"setupId": 2,
"insurancePolicyId": null,
"collateralId": 2,
"linkedLoan": null,
"modId": null,
"modTotal": 0,
"humanActivityDate": "/Date(1463011200)/",
"created": "/Date(1459370262)/",
"active": 1,
"archived": 0,
"loanAlert": null,
"temporaryAccount": 0,
"deleted": null,
"deletedAt": null,
"_relatedMetadata": null,
"_dynamicProperties": null
}
}

Expanding Multiple Entities

Great! We can now get collateral information, but what if we also want the Insurance information as well? According to the OData Standard, the value for the $expand parameter is a comma separated list of the entities we wish to expand. That means, to get our Insurance and our Collateral information, our request would be as follows:

GET https://loanpro.simnang.com/api/public/api/1/odata.svc/Loans(id=2)?$expand=Collateral,Insurance

Your response should look similar to this:

{
"d": {
"__metadata": {
"uri": "https://loanpro.simnang.com/api/public/api/1/odata.svc/Loans(id=2)",
"type": "Entity.Loan"
},
"Insurance":
"__metadata": {
"uri": "https://loanpro.simnang.com/api/public/api/1/odata.svc/Insurance(id=2)",
"type": "Entity.LoanInsurance"
},
"Loan": {
"__deferred": {
"uri": "Insurance(id=2)/Loan"
}
},
"CustomFieldValues": {
"__deferred": {
"uri": "Insurance(id=2)/CustomFieldValues"
}
},
"id": 2,
"companyName": "Insurance Company",
"insured": "Demo Borrower",
"agentName": "Agent",
"policyNumber": "POLICY 123",
"phone": null,
"deductible": "500.00",
"startDate": "/Date(1462060800)/",
"endDate": "/Date(1463616000)/",
"owner": 0
},
"CustomFieldValues": {
"__deferred": {
"uri": "Loans(id=2)/CustomFieldValues"
}
},
"ChecklistItemValues": {
"__deferred": {
"uri": "Loans(id=2)/ChecklistItemValues"
}
},
"Documents": {
"__deferred": {
"uri": "Loans(id=2)/Documents"
}
},
"Collateral": {
"__metadata": {
"uri": "https://loanpro.simnang.com/api/public/api/1/odata.svc/Collateral(id=2)",
"type": "Entity.Collateral"
},
"Loan": {
"__deferred": {
"uri": "Collateral(id=2)/Loan"
}
},
"CustomFieldValues": {
"__deferred": {
"uri": "Collateral(id=2)/CustomFieldValues"
}
},
"id": 2,
"loanId": 2,
"a": null,
"b": null,
"c": null,
"d": null,
"additional": null,
"collateralType": "collateral.type.other",
"vin": null,
"distance": null,
"bookValue": null,
"color": null,
"gpsStatus": null,
"gpsCode": null,
"licensePlate": null,
"gap": null,
"warranty": null
},
...
"id": 2,
"displayId": "44449817",
"title": "44449817",
"settingsId": 2,
"setupId": 2,
"insurancePolicyId": null,
"collateralId": 2,
"linkedLoan": null,
"modId": null,
"modTotal": 0,
"humanActivityDate": "/Date(1463011200)/",
"created": "/Date(1459370262)/",
"active": 1,
"archived": 0,
"loanAlert": null,
"temporaryAccount": 0,
"deleted": null,
"deletedAt": null,
"_relatedMetadata": null,
"_dynamicProperties": null
}
}

Expanding Nested Entities

Now we have our collateral and the insurance for our collateral. But, what if we want to see the custom field values for the insurance? Well, the OData Protocol has us covered yet again. For each nested entity to expand, we append it to the parent entity that holds it using a slash “/”. This is much like a file structure. Each entity is its own folder, and each folder can have nested folders (or entities). The base request specifies our root folder (or our base entity), and then to get information of nested entities we have to specify the path. Paths are comma separated as well, so if you want to get information for two paths (say, A/B and C/D) the $expand attribute would be $expand=A/B,C/D

This also applies for normal entities (ex. to get A/B and C/D and E the $expand attribute would be $expand=A/B,C/D,E).

This means to get the custom fields for insurance, our path would be Insurance/CustomFieldValues. So, our request would be as follows (to get Insurance, Collateral, and Custom field values for Insurance).

GET https://loanpro.simnang.com/api/public/api/1/odata.svc/Loans(id=2)?$expand=Collateral,
Insurance,Insurance/CustomFieldValues

Below is the response:

{
"d": {
"__metadata": {
"uri": "https://loanpro.simnang.com/api/public/api/1/odata.svc/Loans(id=2)",
"type": "Entity.Loan"
},
"Insurance":
"__metadata": {
"uri": "https://loanpro.simnang.com/api/public/api/1/odata.svc/Insurance(id=2)",
"type": "Entity.LoanInsurance"
},
"Loan": {
"__deferred": {
"uri": "Insurance(id=2)/Loan"
}
},
"CustomFieldValues": {
"results": [
{
"__metadata": {
"uri": "https://loanpro.simnang.com/api/public/api/1/odata.svc/CustomFieldValues(id=1305)",
"type": "Entity.CustomFieldValue"
},
"CustomField": {
"__deferred": {
"uri": "CustomFieldValues(id=1305)/CustomField"
}
},
"id": 1305,
"entityId": 2,
"entityType": "Entity.Insurance",
"customFieldId": 261,
"customFieldValue": null
}
]
},
"id": 2,
"companyName": "Insurance Company",
"insured": "Demo Borrower",
"agentName": "Agent",
"policyNumber": "POLICY 123",
"phone": null,
"deductible": "500.00",
"startDate": "/Date(1462060800)/",
"endDate": "/Date(1463616000)/",
"owner": 0
},
"CustomFieldValues": {
"__deferred": {
"uri": "Loans(id=2)/CustomFieldValues"
}
},
"ChecklistItemValues": {
"__deferred": {
"uri": "Loans(id=2)/ChecklistItemValues"
}
},
"Documents": {
"__deferred": {
"uri": "Loans(id=2)/Documents"
}
},
"Collateral": {
"__metadata": {
"uri": "https://loanpro.simnang.com/api/public/api/1/odata.svc/Collateral(id=2)",
"type": "Entity.Collateral"
},
"Loan": {
"__deferred": {
"uri": "Collateral(id=2)/Loan"
}
},
"CustomFieldValues": {
"__deferred": {
"uri": "Collateral(id=2)/CustomFieldValues"
}
},
"id": 2,
"loanId": 2,
"a": null,
"b": null,
"c": null,
"d": null,
"additional": null,
"collateralType": "collateral.type.other",
"vin": null,
"distance": null,
"bookValue": null,
"color": null,
"gpsStatus": null,
"gpsCode": null,
"licensePlate": null,
"gap": null,
"warranty": null
},
...
"id": 2,
"displayId": "44449817",
"title": "44449817",
"settingsId": 2,
"setupId": 2,
"insurancePolicyId": null,
"collateralId": 2,
"linkedLoan": null,
"modId": null,
"modTotal": 0,
"humanActivityDate": "/Date(1463011200)/",
"created": "/Date(1459370262)/",
"active": 1,
"archived": 0,
"loanAlert": null,
"temporaryAccount": 0,
"deleted": null,
"deletedAt": null,
"_relatedMetadata": null,
"_dynamicProperties": null
}
}

This also means to get the Loan Sub Status information for the Loan Status for our loan settings for our loan, our path would be LoanSettings/LoanStatus/LoanSubStatus (go ahead and try it out!).


How did we do?


Powered by HelpDocs (opens in a new tab)