0
# Configuration and Utilities
1
2
Client configuration, URL building, header management, and utility functions for customizing WebApiClient behavior and accessing low-level functionality.
3
4
## Capabilities
5
6
### Client Configuration
7
8
Global configuration properties for customizing WebApiClient behavior.
9
10
```typescript { .api }
11
import * as bluebird from "bluebird";
12
13
/** CRM Web API version to use (default: "8.0") */
14
let ApiVersion: string;
15
16
/** Automatically retrieve all pages for multi-page results (default: false) */
17
let ReturnAllPages: boolean;
18
19
/** Format errors in readable format vs raw JSON (default: true) */
20
let PrettifyErrors: boolean;
21
22
/** Send requests asynchronously vs synchronously (default: true) */
23
let Async: boolean;
24
25
/** Base URL for single page application scenarios */
26
let ClientUrl: string;
27
28
/** Authentication token for single page application scenarios */
29
let Token: string;
30
31
/** WebApiClient library version */
32
let Version: string;
33
34
/** Bluebird promise implementation used internally */
35
let Promise: typeof bluebird;
36
```
37
38
**Configuration Examples:**
39
40
```typescript
41
// Basic configuration
42
WebApiClient.ApiVersion = "9.0";
43
WebApiClient.ReturnAllPages = true;
44
WebApiClient.PrettifyErrors = false;
45
WebApiClient.Async = true;
46
47
// Single Page Application configuration
48
WebApiClient.ClientUrl = "https://orgname.crm.dynamics.com/api/data/v9.0/";
49
WebApiClient.Token = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJS...";
50
WebApiClient.ApiVersion = "9.0";
51
52
// Power Pages configuration
53
WebApiClient.ClientUrl = "/_api/";
54
55
// Access Bluebird promise library
56
const customPromise = WebApiClient.Promise.resolve(data);
57
```
58
59
### URL and Entity Utilities
60
61
Functions for building URLs and working with entity names.
62
63
```typescript { .api }
64
/**
65
* Get the base Web API URL for the current CRM context
66
* @returns Base URL string for Web API endpoints
67
*/
68
function GetApiUrl(): string;
69
70
/**
71
* Get the entity set name for an entity logical name
72
* @param entity - Entity logical name (e.g., "account", "contact")
73
* @returns Entity set name for Web API URLs (e.g., "accounts", "contacts")
74
*/
75
function GetSetName(entity: string): string;
76
```
77
78
**Usage Examples:**
79
80
```typescript
81
// Get API base URL
82
const apiUrl = WebApiClient.GetApiUrl();
83
console.log(apiUrl); // https://orgname.crm.dynamics.com/api/data/v9.0/
84
85
// Get entity set names
86
const accountSetName = WebApiClient.GetSetName("account");
87
console.log(accountSetName); // "accounts"
88
89
const contactSetName = WebApiClient.GetSetName("contact");
90
console.log(contactSetName); // "contacts"
91
92
const userSetName = WebApiClient.GetSetName("systemuser");
93
console.log(userSetName); // "systemusers"
94
95
// Build custom URLs
96
const customUrl = WebApiClient.GetApiUrl() + WebApiClient.GetSetName("account") +
97
"?$select=name,revenue&$filter=statecode eq 0";
98
```
99
100
### Header Management
101
102
Headers are managed per-request using the headers parameter in request objects.
103
104
```typescript { .api }
105
interface Header {
106
/** Header name */
107
key: string;
108
/** Header value */
109
value: string;
110
}
111
```
112
113
**Usage Examples:**
114
115
```typescript
116
// Add custom headers to individual requests
117
await WebApiClient.Create({
118
entityName: "account",
119
entity: { name: "Test Account" },
120
headers: [
121
{ key: "Prefer", value: "return=representation" },
122
{ key: "CustomHeader", value: "CustomValue" }
123
]
124
});
125
126
// Authentication header for external access
127
await WebApiClient.Retrieve({
128
entityName: "account",
129
entityId: accountId,
130
headers: [
131
{ key: "Authorization", value: "Bearer " + accessToken }
132
]
133
});
134
135
// CSRF token for Power Pages
136
await WebApiClient.Update({
137
entityName: "account",
138
entityId: accountId,
139
entity: { name: "Updated Name" },
140
headers: [
141
{ key: "__RequestVerificationToken", value: csrfToken }
142
]
143
});
144
```
145
146
### Low-Level Request Function
147
148
Direct HTTP request function for custom operations not covered by other methods.
149
150
```typescript { .api }
151
/**
152
* Send a raw HTTP request to the Web API
153
* @param method - HTTP method (GET, POST, PATCH, DELETE, etc.)
154
* @param url - Full URL for the request
155
* @param payload - Request payload object
156
* @param parameters - Additional request parameters
157
* @returns Promise resolving to response data
158
*/
159
function SendRequest(
160
method: string,
161
url: string,
162
payload: object,
163
parameters?: BaseParameters
164
): Promise<any> | any | BatchRequest;
165
```
166
167
**Usage Examples:**
168
169
```typescript
170
// Custom action execution
171
const actionUrl = WebApiClient.GetApiUrl() + "WinOpportunity";
172
const result = await WebApiClient.SendRequest("POST", actionUrl, {
173
Status: 3,
174
OpportunityClose: {
175
subject: "Won the deal!",
176
actualrevenue: 100000,
177
"opportunityid@odata.bind": "/opportunities(" + opportunityId + ")"
178
}
179
});
180
181
// Custom query with complex URL
182
const complexUrl = WebApiClient.GetApiUrl() +
183
WebApiClient.GetSetName("account") +
184
"?$select=name,revenue&$expand=contact_customer_accounts($select=fullname,emailaddress1)";
185
186
const complexResults = await WebApiClient.SendRequest("GET", complexUrl, null);
187
188
// Custom entity operation
189
const customEntityUrl = WebApiClient.GetApiUrl() +
190
WebApiClient.GetSetName("new_customentity") +
191
"(" + entityId + ")/Microsoft.Dynamics.CRM.new_CustomAction";
192
193
const customResult = await WebApiClient.SendRequest("POST", customEntityUrl, {
194
InputParameter: "value"
195
}, {
196
headers: [{ key: "Prefer", value: "return=representation" }]
197
});
198
```
199
200
### Navigation Property Expansion
201
202
Collection-valued navigation properties can be expanded using the $expand query parameter in retrieve operations.
203
204
**Usage Example:**
205
206
```typescript
207
// Retrieve records with collection expansion
208
const accountsWithContacts = await WebApiClient.Retrieve({
209
entityName: "account",
210
queryParams: "?$select=name&$expand=contact_customer_accounts($select=fullname,emailaddress1)"
211
});
212
213
console.log("Accounts with expanded contacts:", accountsWithContacts.value);
214
215
// Handle paginated expanded results
216
for (const account of accountsWithContacts.value) {
217
if (account["contact_customer_accounts@odata.nextLink"]) {
218
// Additional requests needed for remaining pages
219
console.log("More contacts available at:", account["contact_customer_accounts@odata.nextLink"]);
220
}
221
}
222
```
223
224
### Promise Integration
225
226
Access to the Bluebird promise library used internally for advanced promise operations.
227
228
```typescript { .api }
229
/** Bluebird promise implementation with additional methods */
230
let Promise: typeof bluebird;
231
```
232
233
**Usage Examples:**
234
235
```typescript
236
// Use Promise.all for concurrent operations
237
const promises = [
238
WebApiClient.Retrieve({ entityName: "account", entityId: account1Id }),
239
WebApiClient.Retrieve({ entityName: "account", entityId: account2Id }),
240
WebApiClient.Retrieve({ entityName: "account", entityId: account3Id })
241
];
242
243
const allAccounts = await WebApiClient.Promise.all(promises);
244
245
// Use Promise.map for processing arrays
246
const accountIds = ["id1", "id2", "id3", "id4", "id5"];
247
248
const accountDetails = await WebApiClient.Promise.map(accountIds, async (id) => {
249
return WebApiClient.Retrieve({
250
entityName: "account",
251
entityId: id,
252
queryParams: "?$select=name,revenue"
253
});
254
}, { concurrency: 3 }); // Process 3 at a time
255
256
// Use additional Bluebird methods
257
const timeoutResult = await WebApiClient.Retrieve({
258
entityName: "account",
259
queryParams: "?$select=name"
260
})
261
.timeout(5000) // 5 second timeout
262
.catch(WebApiClient.Promise.TimeoutError, (error) => {
263
console.log("Request timed out");
264
return { value: [] }; // Return empty result
265
});
266
```
267
268
## Environment-Specific Configuration
269
270
### CRM Forms and Web Resources
271
272
When running within CRM forms or web resources, the client automatically detects the context:
273
274
```typescript
275
// No additional configuration needed - automatic context detection
276
const currentUser = await WebApiClient.Execute(WebApiClient.Requests.WhoAmIRequest);
277
```
278
279
### Power Pages (PowerApps Portals)
280
281
```typescript
282
// Configure for Power Pages
283
WebApiClient.ClientUrl = "/_api/";
284
285
// Add CSRF token for updates (get from shell.getTokenDeferred())
286
const csrfToken = await shell.getTokenDeferred();
287
WebApiClient.AppendToDefaultHeaders({
288
key: "__RequestVerificationToken",
289
value: csrfToken
290
});
291
```
292
293
### Single Page Applications
294
295
```typescript
296
// Configure for external SPA
297
WebApiClient.Configure({
298
ClientUrl: "https://orgname.crm.dynamics.com/api/data/v9.0/",
299
Token: "Bearer " + oauthToken,
300
ApiVersion: "9.0"
301
});
302
303
// Or using header
304
WebApiClient.ClientUrl = "https://orgname.crm.dynamics.com/api/data/v9.0/";
305
WebApiClient.AppendToDefaultHeaders({
306
key: "Authorization",
307
value: "Bearer " + oauthToken
308
});
309
```
310
311
## Advanced Configuration
312
313
### Custom Entity Set Names
314
315
For entities with non-standard naming:
316
317
```typescript
318
// Use overriddenSetName for unusual entity set names
319
await WebApiClient.Create({
320
overriddenSetName: "contactleadscollection", // Instead of auto-generated name
321
entity: { name: "Custom Entity" }
322
});
323
```
324
325
### Synchronous Operations
326
327
```typescript
328
// Global synchronous mode
329
WebApiClient.Async = false;
330
331
// Per-request synchronous mode
332
const syncResult = WebApiClient.Retrieve({
333
entityName: "account",
334
entityId: accountId,
335
async: false
336
});
337
```
338
339
### Error Handling Configuration
340
341
```typescript
342
// Raw JSON errors instead of formatted messages
343
WebApiClient.PrettifyErrors = false;
344
345
try {
346
await WebApiClient.Create({
347
entityName: "account",
348
entity: { invalid_field: "value" }
349
});
350
} catch (error) {
351
// With PrettifyErrors = false, error contains full JSON response
352
const errorJson = JSON.parse(error);
353
console.log("Error code:", errorJson.error.code);
354
console.log("Error message:", errorJson.error.message);
355
}
356
```
357
358
### API Version Management
359
360
```typescript
361
// Set specific API version
362
WebApiClient.ApiVersion = "9.2";
363
364
// Per-request API version override
365
await WebApiClient.Create({
366
entityName: "account",
367
entity: { name: "Test" },
368
apiVersion: "8.2"
369
});
370
```