How to call Business Central Online APIs from Node.js Application

This post explains how to read data from Microsoft Dynamics 365 Business Central (Online) APIs in a Node.js application, and also how to configure App registrations in Azure Portal that can be used in Node.js console application to get Access Token and a sample code that acquires access token using Windows Azure Active Directory Authentication Library (ADAL) for Node.js, and retrieve companies data from Companies Web API.


App registration

The following sections explains how to register Application in Azure Portal for Node.js console application with API access to D365 Business Central (Online).


Register a new Application

1. Login to Azure Portal with your Azure AD account.

2. Search for App registrations in the search box and select App registrations > New registration.

3. Enter the application name, select the selected supported account type, and click the Register button.

4. Azure AD will assign a unique Client ID and an Object ID. These details can be seen in the Overview page.


Authentication

1. Select Authentication, scroll down to Advanced Settings > Allow public client flows and select Enable the following mobile and desktop flows.


Permissions and Consent

1. Select API Permissions and go to Add a permission

2. Select Dynamics 365 Business Central in the Request API permissions page.

3. Select Delegated permissions, check user_impersonation and Financials.ReadWrite.All permissions, and click the Add permissions button.

4. Click the Grant admin consent for Contoso button to grant admin consent to this application.

5. After providing admin consent in API permissions page, status should be “Granted for Contoso”.


Node.js Application

Following is the typescript code to get access token from Azure Active Directory using OAuth2 authentication and to get the companies data from D365 Business Central (Online) APIs.


bc-connector.ts

BCConnector class is used to get access token using ADAL library. The connect is a function which calls ADAL's acquireToken functions and return a promise of access token.

import * as adal from 'adal-node';

export class BCConnector {
    authorityUrl: string;
    resource: string;
    adalContext: adal.AuthenticationContext;
    tokenResponse?: adal.TokenResponse;

    constructor(tenantId: string, resource: string, private clientId: string, private username: string, private password: string) {
        this.authorityUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/token`;
        this.resource = `https://${resource}/`;

        this.adalContext = new adal.AuthenticationContext(this.authorityUrl);
    }

    connect(): Promise<adal.TokenResponse> {
        return new Promise((resolve, reject) => {
            const adalCallback: adal.AcquireTokenCallback = (error: Error, response: adal.TokenResponse | adal.ErrorResponse) => {
                if (!error) {
                    console.log('Authentication successful.');
                    this.tokenResponse = response as adal.TokenResponse;
                    resolve(this.tokenResponse);
                }
                else {
                    console.log('Authentication failed.');
                    reject(error);
                }
            }

            console.log('Authenticating ....');
            if (this.tokenResponse && this.tokenResponse.refreshToken) {
                this.adalContext.acquireTokenWithRefreshToken(this.tokenResponse.refreshToken, this.clientId, this.resource, adalCallback);
            } else {
                this.adalContext.acquireTokenWithUsernamePassword(this.resource, this.username, this.password, this.clientId, adalCallback);
            }
        });
    }
}

index.ts

The following code gets the access token using BCConnector class and calls the Business Central companies API using http request to get the companies data.


import { BCConnector } from './bc-connector';
import * as https from 'https';

const tenantId = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx';
const clientId = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx';
const hostName = 'api.businesscentral.dynamics.com';
const userName = 'admin@xxxx.onmicrosoft.com';
const password = 'xxxxxxxx';

const dynamics = new BCConnector(tenantId,
    hostName,
    clientId,
    userName,
    password);

dynamics.connect().then(response => {
    console.log(`retrieving data from bc...`);
    var req = https.request({
        hostname: 'api.businesscentral.dynamics.com',
        path: '/v2.0/production/api/v2.0/companies',
        headers: {
            "accept": "application/json",
            "Authorization": `Bearer ${response.accessToken}`
        }
    }, res => {
        res.on('data', d => {
            const responseJson = JSON.parse(d.toString());
            console.log(JSON.stringify(responseJson, null, 2));
        })
    });

    req.on('error', error => {
        console.error(error)
    })

    req.end();
}).catch(error => {
    console.error(error);
});

Output

The following is the output from the Node.js console application.

Authenticating ....                                                                                             
Authentication successful.                                                                                      
retrieving data from bc...                                                                                      
{                                                                                                               
  "@odata.context": "https://api.businesscentral.dynamics.com/v2.0/Production/api/v2.0/$metadata#companies",    
  "value": [                                                                                                    
    {                                                                                                           
      "id": "f53e0828-3d8a-eb11-bb5f-000d3a398a56",                                                             
      "systemVersion": "19.3.34541.34662",                                                                      
      "name": "CRONUS USA, Inc.",                                                                               
      "displayName": "",                                                                                        
      "businessProfileId": "",                                                                                  
      "systemCreatedAt": "2021-03-21T12:01:27.08Z",                                                             
      "systemCreatedBy": "00000000-0000-0000-0000-000000000001",                                                
      "systemModifiedAt": "2021-03-21T12:01:27.08Z",                                                            
      "systemModifiedBy": "00000000-0000-0000-0000-000000000001"                                                
    },                                                                                                          
    {                                                                                                           
      "id": "c2c5eb36-3d8a-eb11-bb5f-000d3a398a56",                                                             
      "systemVersion": "19.3.34541.34662",                                                                      
      "name": "My Company",                                                                                     
      "displayName": "",                                                                                        
      "businessProfileId": "",                                                                                  
      "systemCreatedAt": "2021-03-21T12:01:50.367Z",                                                            
      "systemCreatedBy": "00000000-0000-0000-0000-000000000001",                                                
      "systemModifiedAt": "2021-03-21T12:01:50.367Z",                                                           
      "systemModifiedBy": "00000000-0000-0000-0000-000000000001"                                                
    }                                                                                                           
  ]                                                                                                             
}                                                                                                               

Conclusion

The above code is just an example to read data from Business Central (Online). In this application, Business Central APIs can be used to perform all types of operations such as create, read, update, etc.


Node.js is a very popular platform to build robust applications, and very easy to develop applications using Node.js. Node.js application can be used as a middleware to integrate Business Central with other applications. Power Automate is a good option for integrations, but if there is a complex logic this would be a better approach.


Happy Coding!!!


Complete source code is available at GitHub.


#MSDyn365 #MSDyn365BC #BusinessCentral #DynamicsNAV #NodeJS #WebAPIs


754 views0 comments

Recent Posts

See All