Delivering the Expected - Solteq Developer Blog

Breaking monolith into microservices by leveraging Web Services (in Microsoft Dynamics NAV/BC ERP)

Servers

Decentralization

We can see the trend that companies, even SMB-sized, are not trying any more to put all data and implement all processes in ERP (like Microsoft Dynamics NAV a.k.a. Business Central).

For instance, in the retail and hospitality business, there can be solutions like LS NAV, when indeed everything can be supported by one, complex system. Even though LS NAV is implemented and covers almost all processes, web store is usually provided by another supplier. Also data warehouse & business intelligence solutions are another examples of systems that comes hand by hand with NAV, but still - they are completely separate solutions and usually provided by different vendors.

Therefore, that’s fair to say that today, the company’s software eco-system is composed of multiple parts, where ERP is used only to some extent (not all possible modules). Let me repeat it: ERP is only one of many parts of the solution and I would even say not the most important one. In fact, there is no the most important system. It is a sort of synergy - each piece of software serves one or multiple purposes and is beneficial from that point of view, but only if all parts are integrated together, they bring the higher values by covering the whole end-to-end processes.

Let me visualize this with the pictures. Below you can see old approach - where ERP is the center of the world. Although there are other systems, almost all data goes somehow through ERP: Architecture - Centralized

In the next picture we can see decentralized architecture. ERP is not just one monolith, but its responsibility is distributed to specific areas (modules): Architecture - Decentralized

There are many benefits of the decentralized solution, and one of them is that when the systems are separated, each can be developed (improved/upgraded) separately. This leads us to the microservices world (which as such is another broad topic).

Without starting a debate about what is microservice and what is not, undoubtedly, neither NAV nor BC can be described as a microservice architecture. It is still a monolith architecture. But keeping an eye on the trend and movements from Microsoft side, I think it can change in the future. The extension-driven development empowers it, by making it possible to keep multiple separate, extensions, that each can be independent and serve different purpose (separation of concerns concept).

But even today and without extensions, NAV/BC provides multiple tools, that can be leveraged to build integrations with different kinds of systems.

Microsoft Dynamics NAV / Business Central Integrations

In the past, the main integration method was file exchange. Nowadays, usually Web Services are preferred way. In NAV/BC this is available out-of-the box, and often (as long as the standard functionalities are used) it does not require any customization.

Moreover, Microsoft gives us multiple tools to support Web Services - based integrations:

We described it already some time ago here.

There are really plenty of materials available - both from Microsoft and from different NAV gurus, so one can say: “everything was already said”.

Being always passive is not always enough

After this long, but hopefully not-that-boring introduction, let’s get to the point. The web services work seamlessly, and you do not need even to open development environment to set them up and activate them. That’s fair enough… as long as you want to only expose the data from ERP. In other words: everything is ok if NAV/BC is only passive part. But what if you need to make the NAV/BC behave more actively? For instance if Items are exposed by API and there is a justified requirement that NAV should inform the other systems about new or updated items?

In new API (Microsoft Graph) there are actually WebHooks supported, but there are few problems with them:

Therefore, we need something else. And there are again multiple ways how to approach this seemingly challenging situation.

Old school way

Until now I have seen that usually, when this kind of requirement was identified, the proposed solution has been to develop external component (.dll) in the .Net (C#) and then utilize .Net library in NAV. This solution is preferred by some developers, who have .Net background. At the same time it is hated by pure NAV developers, who feel uncomfortable, when they need to leave NAV development environment. Besides personal preferences, undoubtedly, this make the source code control difficult. Now you have not only C/AL code, but also C# project to maintain.

In AL, we have new native types supporting HTTP calls, XML and JSON manipulation (example: HttpClient, HttpRequestMessage, XMLDocument, JsonArray and many more types supporting rest API (see official documentation ).

I have seen this working fine. I experienced one limitation though: NTLM authentication was not supported and only Basic authentication worked (and that requires SSL certificates for NavUserPassword authentication). Now, according to Microsoft we can expect NTLM authentication in the nearest releases.

Solution is just around the corner

How can we do this in old, good C/AL and without opening Visual Studio?

Side remark about C/AL: yes, I know that Microsoft announced that C/AL will be gone soon. Nevertheless, there is some time before it happens and live goes on, so chances are that you still have to do some development in NAV 2018 using C/AL. Also, as we know upgrades from older versions to BC for complex solutions takes some time, so I suppose as of today still most of the customers are not planning to move to the BC (and extensions) in the nearest future and we need to support them and help them grow their business solution in the current setup.

Well, we can use DotNet variable types for that purpose. It is still quite an effort to build this from scratch. But after scrolling though the standard NAV codeunits from Microsoft, one can notice, that there is something what can be reused and would save a lot of time. Namely, there is a codeunit SOAP Web Service Request Mgt. (ID 1290), which is offering all necessary, fundamental functions to handle web service integration.

So, without any further due, let’s see a specific example - export of Vendors, when this is NAV what is active part. No data is exposed to read, NAV just calls web service and provides the data directly.

PROCEDURE ExportToWebService@10014501();
    VAR
      TempBlob@10014508 : TEMPORARY Record 99008535;
      WebServReqMgt@10014507 : Codeunit 1290;
      ResponseXmlDoc@10014506 : DotNet "'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlDocument";
      ReqBodyOutStream@10014505 : OutStream;
      ReqBodyInStream@10014504 : InStream;
      RespBodyInStream@10014503 : InStream;
      Url@10014502 : Text;
      Username@10014501 : Text;
      Password@10014500 : Text;
      ResponseCode@10014512 : Text;
      ErrorText@10014511 : Text;
    BEGIN
	//Some filtering for Vendor record (if needed) goes here
	
	Url := 'https://contoso.com/api/vendors';
	
	TempBlob.Blob.CREATEOUTSTREAM(ReqBodyOutStream);
	XMLPORT.EXPORT(50000,ReqBodyOutStream,Vendor);
	

      TempBlob.Blob.CREATEINSTREAM(ReqBodyInStream);

      WebServReqMgt.SetGlobals(ReqBodyInStream,Url,Username,Password);
       
      WebServReqMgt.SetContentType('text/xml');
      WebServReqMgt.SendRequestToWebService;

      WebServReqMgt.GetResponseContent(RespBodyInStream);
      ResponseXmlDoc := ResponseXmlDoc.XmlDocument;
      ResponseXmlDoc.Load(RespBodyInStream);
      MESSAGE('Response: ' + ResponseXmlDoc.InnerXml)
    END;

The code above is used to construct the http request (data generated by XMLPort), set up all parameters, call web service and display the response.

Please note how easy it is to create the SOAP WebService request using the XMLPort as the source of the data. Also, remember that there are even more helpful functions. For instance setting the timeout. So if we have to perform huge export of data, we can extend the timeout by adding this line, before calling the SendRequestToWebService funtion:

WebServReqMgt.SetTimeout(60000);

Another useful feature is the trace mode - for debugging/troubleshooting possibilities. It is as simple as calling this function (before SendRequestToWebService)

WebServReqMgt.SetTraceMode(TRUE);

and once it is done, then after every request there will be set of four files created in the temporary server folder: request and response file pair and the same wrapped with the SOAP envelope.

Of course it can also work in the other scenario when NAV does not send the data, but asks for some data from other system. In that case, it would require some processing of the response content (using XML codeunit 6224:XMLDOMManagement).

Summary

There are multiple options how to integrate Dynamics NAV / BS with other system using Web Services. Some of them (exposing the data) requires usually only configuration while the others must be developed. Nevertheless, even if there is a need to develop web service (e.g. when NAV should actively sends the data), there is no need to deep dive in .NET classes and develop a .dll from that. In AL we use new native object types for that. For C/AL Microsoft provides already codeunits that wraps up .Net powerful possibilities.




Join us?

See what we have to offer - Careers