API - Adding and Updating Nested Entities

This article assumes that you have read Nested EntitiesAPI – Updating Entities, and API – Expanding objects.

There are many times in which the best, and sometimes only way, to get the proper entity information is through a parent entity. However, this does pose the issue of how to update that information once you’ve obtained it. Luckily, OData has it covered.

The Request

To update a nested entity, you will send a PUT request to the uppermost parent entity. This means that to update the Employer information for a Customer, you would send a PUT request to the Customers entity that holds the Employer entity you wish to update. Likewise, to update the Address of an Employer for a Customer you would send the PUT request to the Customers entity. This may seem a little long-winded and unnecessary, but it does allow updating the Customer, Employer, and Address entities all in one request – which can be a huge advantage!

To add a nested entity that does not already exist, you would send the exact same request to update, but only change a few fields. We’ll identify those fields later on.

The Body

Now that we know where the request will go, we now need to create the body of the request.

We’re assuming that you’ve ran a few GET requests up to this point (if you haven’t, please do). You’ve probably noticed that the data comes in with references pointing to each entity (unless you use $expand). As an example, below is the response of getting customer data:

{
"d": {
"__metadata": {
"uri": "https://loanpro.simnang.com/api/public/api/1/odata.svc/Customers(id=1)",
"type": "Entity.Customer"
},
"PrimaryAddress": {
"__deferred": {
"uri": "Customers(id=1)/PrimaryAddress"
}
},
"MailAddress": {
"__deferred": {
"uri": "Customers(id=1)/MailAddress"
}
},
"Employer": {
"__deferred": {
"uri": "Customers(id=1)/Employer"
}
},
"References": {
"__deferred": {
"uri": "Customers(id=1)/References"
}
},
"PaymentAccounts": {
"__deferred": {
"uri": "Customers(id=1)/PaymentAccounts"
}
},
"Phones": {
"__deferred": {
"uri": "Customers(id=1)/Phones"
}
},
"CustomFieldValues": {
"__deferred": {
"uri": "Customers(id=1)/CustomFieldValues"
}
},
"Documents": {
"__deferred": {
"uri": "Customers(id=1)/Documents"
}
},
"CreditScore": {
"__deferred": {
"uri": "Customers(id=1)/CreditScore"
}
},
"Loans": {
"__deferred": {
"uri": "Customers(id=1)/Loans"
}
},
"SocialProfiles": {
"__deferred": {
"uri": "Customers(id=1)/SocialProfiles"
}
},
"id": 1,
"customId": null,
"mcId": null,
"customerType": "customer.type.individual",
"status": "Active",
"firstName": "John",
"lastName": "Doe",
"middleName": "S",
"birthDate": "/Date(232329600)/",
"gender": "customer.gender.male",
"generationCode": "customer.generationCode.none",
"email": "johndoe@nonexistant.com",
"ssn": "111111111",
"driverLicense": "11111111",
"companyName": null,
"contactName": null,
"customerIdType": "customer.idType.ssn",
"customerId": null,
"creditLimit": 0,
"accessUserName": "john.doe2132132",
"accessPassword": null,
"active": 1,
"ofacMatch": 0,
"ofacTested": 0,
"hasAvatar": 0,
"loanRole": null,
"created": "/Date(1458663961)/",
"lastUpdate": "/Date(1465579531)/",
"creditScoreId": 1
}
}

As you can see, we have all of these nested entity references. This tells us the names of each nested entity we can use. To know the types to use, please refer to the proper documentation.

Let’s continue with our example of updating Employer information for a Customer. We have the customer information above, so let’s first add, and then update Employer information for that customer.

Adding Nested Entities

Adding is rather simple. We send a PUT request to the URL of the base parent. We’ll then send the contents of the Employer entity that we want to have added as a nested entity. (At the same time you can optionally update the Customer entity, but we won’t worry about that).

Let’s say our customer, John Doe (from above), works at the local high school as a janitor, was hired on May 19, 2016 and gets paid $10.50 hour for part-time janitorial work. Their next pay date was reported to be on June 19, 2016. We also know the school’s phone number, and that they get paid bi-weekly. Our Employer information would look like the following JSON object:

{
"phone": "5555555555",
"payDate": "2016-06-19",
"hireDate": "2016-05-19",
"incomeFrequency": "customerEmployer.incomeFrequency.annually",
"payDateFrequency": "customerEmployer.payDateFrequency.biWeekly",
"income": "10500.00",
"companyName": "Local High School",
"title": "Janitor"
}

But, we aren’t sending a request to the employer’s entity; instead, we’re sending it to the Customer entity! If we send the JSON object as it is now, LoanPro will try to update the customer entity, fail, and then throw an error back at us. So, we need to tell LoanPro that we want to update the nested Employer entity and not the customer entity. We do this by having the outermost JSON object represent the Customer, and then set the Employer value (of the customer) to be our Employer JSON Object, as follows:

PUT https://loanpro.simnang.com/api/public/api/1/odata.svc/Customers(1)
{
"Employer": {
"phone": "5555555555",
"payDate": "2016-06-19",
"hireDate": "2016-05-19",
"incomeFrequency": "customerEmployer.incomeFrequency.annually",
"payDateFrequency": "customerEmployer.payDateFrequency.biWeekly",
"income": "10500.00",
"companyName": "Local High School",
"title": "Janitor"
}
}

This will then tell LoanPro to add the Employer object to the parent customer object. If we want to change John’s middle name to “Smith” in the same request, we can do that by sending the following request instead:

PUT https://loanpro.simnang.com/api/public/api/1/odata.svc/Customers(1)
{
"Employer": {
"phone": "5555555555",
"payDate": "2016-06-19",
"hireDate": "2016-05-19",
"incomeFrequency": "customerEmployer.incomeFrequency.annually",
"payDateFrequency": "customerEmployer.payDateFrequency.biWeekly",
"income": "10500.00",
"companyName": "Local High School",
"title": "Janitor"
},
"__id":1,
"__update":true,
"middleName":"Smith"
}

To get the information (including the ID), we’ll need to send the following GET request:

GET https://loanpro.simnang.com/api/public/api/1/odata.svc/Customers(1)?$expand=Employer

Updating Nested Entities

Alright, so we entered John’s employer information, and it’s all going well until we realize that he works at the local junior high school instead. Whoops! Well, we already created the Employer entity, so we can’t just send the same request. We have to instead update the existing employer entity. Luckily, this is fairly easy. All we do is add the two fields described in API – Updating Entities (namely “__id” and “__update”), and then we include the fields that we want to update inside of the nested Employer Entity. In short, our request would be the following (assuming the ID of our employer is 23; send one of the above GET requests to verify first):

PUT https://loanpro.simnang.com/api/public/api/1/odata.svc/Customers(1)
{
"Employer": {
"__id":23,
"__update":true,
"companyName": "Local Junior High School"
},
"__id":1,
"__update":true,
"middleName":"Smith"
}

And that’s it!

Multi-Nesting Entities

When an entity is several layers inside of entities, the same principles apply. You send a PUT request to the outermost entity, and then you send the JSON object for each nested entity along the way. So, to add an address to John’s employer, we would send the following:

PUT https://loanpro.simnang.com/api/public/api/1/odata.svc/Customers(1)
{
"Employer": {
"Address": {
"address1": "53 321 Street",
"address2": null,
"city": "HENEFER",
"state": "geo.state.NJ",
"zipcode": "840331342",
"country": "company.country.usa",
"geoLat": "41.017894",
"geoLon": "-111.4879125",
"active": 1,
"isVerified": 0
}
}
}

To get the ID of it, we would send the following GET request:

GET https://loanpro.simnang.com/api/public/api/1/odata.svc/Customers(1)?$expand=Employer/Address

Assuming the Address ID is 142, to update it (say, change the city), we would send the following request :

PUT https://loanpro.simnang.com/api/public/api/1/odata.svc/Customers(1)
{
"Employer": {
"Address": {
"__id": "142",
"__update": true,
"city": "Chicago"
}
}
}


How did we do?


Powered by HelpDocs (opens in a new tab)