04 May 2020

How to use a custom SystemId when inserting a record through an API

Have you tried to insert a record to Microsoft Dynamics 365 Business Central through a Custom API and pass a custom SystemId with the record? 

Basically what I trying to achieve is when an Account is created in the D365 Sales system, I want to pass that record to D365 Business Central. I can easily do that using D365 Business Central APIs. However one of the challenges I faced was how I going to do the mapping between D365 Sales records and D365 Business Central Records. 


I can use intermediate tables and maintain record mapping. This is the solution most of the implementations used. This will still be the ideal solution if you have multiple D365 Sales systems connecting to D365 Business Central. 


If you have a one to one mapping between D365 Sales and D365 Business Central you can use a different approach. You can directly create a mapping between records without going through an intermediate mapping table. 


D365 Sales use a GUID as the record primary key and in 
most of the time, D365 Business Central use Code 20 field. How I'm going to create a mapping between records without modifying D365 Business Central or D365 Sales system? 

I can use SystemID in the D365 Business Central to handle this situation. 


So now what I'm trying to achieve is pass the Dynamics Sales Account ID into Business Central Customer System Id field. This will allow me to update the records back to Dynamics 365 Sales without maintaining a separate mapping table.


As a first step, I created a custom API for customer entity in D365 Business Central and exposed few fields. 



Then make a POST request with a sample JSON body and pass the No, Name, Email and D365 Sales Entity Record ID as SystemId. 



Strangely first error encountered was "systemId is read-only". Looks like platform automatically set the Editable property of the SystemId field to FALSE as a safety precaution. 


I set the editable property of the SystemId field to editable in the API page.


Then I tried the POST API call again and this time D365 Business Central accepted my POST request. However, the SystemId was different from the one that I used in the POST request. 


It is due to the platform is overriding the SystemId I pass through the POST request. To handle this new challenge of D365 Business Central generating the SystemID at the insert event, I can handle the insert within the API page by adding below event trigger. 

Some of you might be wondering "why Insert trigger is called with two boolean values?"


The Insert(Boolean, Boolean) lets you specify the SystemId value for a record, instead of using one assigned by the platform:
 myRec.SystemId := '{B6666666-F5A2-E911-8180-001DD8B7338E}';   
 myRec.Insert(true, true);  

Also, since we already inserted the record by calling Insert trigger, I should exit the function by returning FALSE. If I did return TRUE system will try to insert the same record again and we will get an error saying the record already exists.

This time when I call the POST method (of course I deleted the record inserted in the previous call) it did insert the customer record with the systemId I passed in the JSON body. 


The final result of the API page looks like below: 


If you want to access the AL files and the extension related to this blog please use below GitHub Repo: 
https://github.com/Tharangac/bc-bloggingAPI

Please provide your feedback with a comment. 
Thank you and Regards,
Tharanga Chandrasekara
Read more »