AleksandrRogov / DynamicsWebApi

DynamicsWebApi is a Microsoft Dataverse Web API helper library for JavaScript & TypeScript
MIT License
268 stars 58 forks source link

Batch operation to create multiple records fails with: 400 - "Requested API Version 'data' was not understood" #130

Closed leon-cgn closed 1 year ago

leon-cgn commented 1 year ago

hey, thanks for this library - sure helps a lot!

I have a weird behavior when trying to batch the create record calls. To create records works just fine but when I wrap the calls with the startBatch() and executeBatch(), I get the following response:

code: '0x80060888',
message: "Requested API Version 'data' was not understood. Please provide in the format /api/data/v<Major>.<Minor>/ (example: /api/data/v7.2/)",
status: 400,
statusText: 'Bad Request'

Creating multiple records works:

import * as MSAL from '@azure/msal-node';
import DynamicsWebApi from 'dynamics-web-api';

const msDynamicsConfig = {
  msalConfig: {
    auth: {
      authority: process.env.AUTH_AUTHORITY,
      clientId: process.env.AUTH_CLIENT_ID,
      clientSecret: process.env.AUTH_CLIENT_SECRET,
      knownAuthorities: ['login.microsoftonline.com'],
    },
  },
  serverUrl: process.env.MS_DYNAMICS_URL,
};

const cca = new MSAL.ConfidentialClientApplication(msDynamicsConfig.msalConfig);

const acquireToken = (dynamicsWebApiCallback: any) => {
  cca
    .acquireTokenByClientCredential({
      scopes: [`${msDynamicsConfig.serverUrl}/.default`],
    })
    .then((response) => {
      //call DynamicsWebApi callback only when a token has been retrieved successfully
      dynamicsWebApiCallback(response?.accessToken);
    })
    .catch((error) => {
      throw error;
    });
};

const dynamicsWebApi = new DynamicsWebApi({
  webApiUrl: `${msDynamicsConfig.serverUrl}/api/data/v9.2/`,
  onTokenRefresh: acquireToken,
  returnRepresentation: true,
});

await dynamicsWebApi.create(
  {
    key: value,
    key1: value1,
  },
  'collection',
  undefined,
  ['return_value']
);
await dynamicsWebApi.create(
  {
    key: value,
    key1: value1,
  },
  'collection',
  undefined,
  ['return_value']
);

but wrapping them will error:

dynamicsWebApi.startBatch();

dynamicsWebApi.create(
  {
    key: value,
    key1: value1,
  },
  'collection',
  undefined,
  ['return_value']
);
dynamicsWebApi.create(
  {
    key: value,
    key1: value1,
  },
  'collection',
  undefined,
  ['return_value']
);

await dynamicsWebApi.executeBatch()

I use v1.7.6, thanks if you look into this. Otherwise I'll just loop over my max. 1000 records-to-be-created

AleksandrRogov commented 1 year ago

@leon-cgn can you try using createRequest instead of create? maybe that could be the issue? for example:


dynamicsWebApi.startBatch();
dynamicsWebApi.createRequest({
    collection: 'collection',
    entity: {
        key: value,
        key1: value1,
    },
    select: ['return_value']
});

// other requests here

await dynamicsWebApi.executeBatch()
leon-cgn commented 1 year ago

@AleksandrRogov that did not work. Same behavior, when used in a loop the requests work fine but inside a batch I get the same error - But I figured it out at another place :) It seems that the webApiUrl property from the DynamicsWebApi instantiation has a problem with string templates when used by the batch logic.

This makes the batch execution fail:

const dynamicsWebApi = new DynamicsWebApi({
  webApiUrl: `${msDynamicsConfig.serverUrl}/api/data/v9.2/`,
...
});

And this works:

const dynamicsWebApi = new DynamicsWebApi({
  webApiUrl: 'https://my_env.api.crm4.dynamics.com/api/data/v9.2/',
...
});
AleksandrRogov commented 1 year ago

@leon-cgn that is interesting, I will take a look. thanks

leon-cgn commented 1 year ago

@AleksandrRogov sorry - fault was on my side! my env var had a "/" at the end and therefore the url was "...com//api/data/v9.2/" - the duplicated "/" seems make a problem in the batch while it runs in the normal create request.

AleksandrRogov commented 1 year ago

@leon-cgn ah. ok.. I could not replicate it and was about to mention that here and to ask you what url it's calling when you were making a batch request. I may need to add a check somewhere to remove a slash from the parameter. glad it's resolved!