@sfdxy/mule-lint 1.21.0 → 1.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,904 +1,111 @@
1
1
  # MuleSoft Development Best Practices
2
2
 
3
- > **Purpose:** Comprehensive guide for building maintainable, secure, and performant Mule applications. This guide covers both practices enforced by mule-lint and general development guidelines for MuleSoft developers.
3
+ > **Purpose:** Comprehensive index to MuleSoft development best practices for building maintainable, secure, and performant Mule 4 applications. Each topic links to a focused guide optimized for both human reading and AI/MCP consumption.
4
+ >
5
+ > **Version:** April 2026 · **Runtime:** Mule 4.10+ · **Java:** 17
4
6
 
5
7
  ---
6
8
 
7
- ## Table of Contents
9
+ ## Quick Navigation
8
10
 
9
- ### Linter-Enforced Practices
11
+ ### Core Development
10
12
 
11
- - [API-Led Connectivity](#api-led-connectivity)
12
- - [Error Handling](#error-handling)
13
- - [Logging Standards](#logging-standards)
14
- - [Security Guidelines](#security-guidelines)
15
- - [Performance Patterns](#performance-patterns)
16
- - [Project Structure](#project-structure)
17
- - [Naming Conventions](#naming-conventions)
18
- - [Configuration Management](#configuration-management)
19
- - [DataWeave Best Practices](#dataweave-best-practices)
20
- - [Documentation Standards](#documentation-standards)
13
+ | Guide | Description | Related Rules |
14
+ | ------------------------------------------- | ---------------------------------------------------------------------------- | ----------------------------------- |
15
+ | [Error Handling](error-handling.md) | Global error handlers, HTTP vs. event-driven patterns, connector error types | `MULE-001` `MULE-003` `ERR-001–004` |
16
+ | [Naming & Variables](variable-contracts.md) | Standard variable contracts, correlation IDs, naming conventions | `MULE-002` `MULE-102` `STD-001` |
17
+ | [Logging](logging.md) | Categories, structured logging, MDC/tracing, PII prevention | `MULE-006` `MULE-301` `LOG-001` |
18
+ | [Security](security.md) | Secure properties, TLS, credential management, zero-trust | `MULE-004` `MULE-201` `SEC-002–010` |
19
+ | [Performance](performance.md) | Timeouts, connection pooling, async patterns, streaming | `MULE-501–503` `PERF-002` `RES-001` |
21
20
 
22
- ### General Developer Guidelines
21
+ ### Architecture & Patterns
23
22
 
24
- - [Testing with MUnit](#testing-with-munit)
25
- - [CI/CD Integration](#cicd-integration)
26
- - [API Versioning](#api-versioning)
27
- - [Deployment Practices](#deployment-practices)
28
- - [Monitoring and Observability](#monitoring-and-observability)
23
+ | Guide | Description | Related Rules |
24
+ | ------------------------------------------------- | ------------------------------------------------------------ | ------------------------------ |
25
+ | [Event-Driven Patterns](event-driven-patterns.md) | Platform events, Anypoint MQ, AsyncAPI, deduplication | `SF-001` `SF-002` |
26
+ | [Connector Patterns](connector-patterns.md) | Entity config, SF/NS connector gotchas, protocol negotiation | `SEC-007` `PERF-002` `RES-001` |
27
+ | [DataWeave Patterns](dataweave-patterns.md) | Modules, type coercion, lookups, import paths | `DW-001–005` |
28
+
29
+ ### Project & Operations
30
+
31
+ | Guide | Description | Related Rules |
32
+ | ----------------------------------------------------- | ----------------------------------------------------- | ------------------------------- |
33
+ | [Folder Structure](folder-structure.md) | Standard Maven layout, file organization | `MULE-802–804` |
34
+ | [Documentation Standards](documentation-standards.md) | Flow docs, README templates, commit messages | `MULE-601` `MULE-604` `DOC-001` |
35
+ | [Testing](testing.md) | MUnit best practices, event-driven testing, coverage | `EXP-003` |
36
+ | [CI/CD Integration](ci-cd.md) | Pipeline stages, mule-lint integration, quality gates | `PROJ-001` `PROJ-002` |
37
+ | [Deployment & Modernization](deployment-2026.md) | CloudHub 2.0, Java 17, ACB, API governance | `OPS-001` |
38
+ | [Rules Catalog](rules-catalog.md) | Complete reference for all 82 lint rules | All |
29
39
 
30
40
  ---
31
41
 
32
- ## API-Led Connectivity
42
+ ## Quick Reference Card
33
43
 
34
- MuleSoft's API-Led Connectivity approach organizes APIs into three layers, each with distinct responsibilities.
44
+ | Practice | Do ✅ | Don't ❌ |
45
+ | ------------------ | ----------------------------------------- | -------------------------------------------- |
46
+ | **Error Handling** | Use global handler, set `httpStatus` | Catch `type="ANY"` first, ignore errors |
47
+ | **Logging** | Use categories, log specific fields | Log `#[payload]`, log in retry loops |
48
+ | **Security** | Use `${secure::...}`, encrypt secrets | Hardcode URLs, passwords, keys |
49
+ | **Performance** | Set timeouts, handle async errors | Unlimited retries, huge choice blocks |
50
+ | **Naming** | kebab-case flows, camelCase vars | Inconsistent casing, no suffixes |
51
+ | **Structure** | Separate files by domain | Monolithic XML files |
52
+ | **Config** | Environment-specific YAML | Hardcoded values |
53
+ | **DataWeave** | External `.dwl` files, reusable modules | Large inline transforms |
54
+ | **Connectors** | Entity config YAML, full DWL import paths | Hardcoded entity details, short import paths |
35
55
 
36
- ### The Three Layers
56
+ ---
57
+
58
+ ## API-Led Connectivity
59
+
60
+ MuleSoft's API-Led Connectivity approach organizes APIs into three layers:
37
61
 
38
62
  ```
39
63
  ┌─────────────────────────────────────────────────────────┐
40
64
  │ Experience Layer │
41
- (Channel-specific: Web, Mobile, Partner APIs)
65
+ │ Channel-specific: Web, Mobile, Partner APIs
42
66
  │ Naming: *-exp-*, *-experience-* │
43
67
  └─────────────────────┬───────────────────────────────────┘
44
68
 
45
69
  ┌─────────────────────▼───────────────────────────────────┐
46
70
  │ Process Layer │
47
- (Orchestration, Business Logic, Aggregation)
48
- │ Naming: *-proc-*, *-process-*
71
+ │ Orchestration, Business Logic, Event Processing
72
+ │ Naming: *-proc-*, *-process-*, *-papi
49
73
  └─────────────────────┬───────────────────────────────────┘
50
74
 
51
75
  ┌─────────────────────▼───────────────────────────────────┐
52
76
  │ System Layer │
53
- (Backend Connectivity: SAP, Salesforce, Databases)
54
- │ Naming: *-sys-*, *-system-*
77
+ │ Backend Connectivity: Salesforce, NetSuite, Databases
78
+ │ Naming: *-sys-*, *-system-*, *-sapi
55
79
  └─────────────────────────────────────────────────────────┘
56
80
  ```
57
81
 
58
- ### Layer Guidelines
59
-
60
- | Layer | Should Have | Should NOT Have |
61
- | -------------- | ------------------------------------------------ | ---------------------------------------------- |
62
- | **Experience** | HTTP listeners, channel-specific transformations | Direct database access, complex business logic |
63
- | **Process** | Flow-refs to other APIs, orchestration logic | Direct system connections, database queries |
64
- | **System** | Database operations, HTTP requests to backends | Business logic, data aggregation |
65
-
66
- ### Example Flow Structure
67
-
68
- ```xml
69
- <!-- Experience Layer: User-facing API -->
70
- <flow name="orders-exp-get-order-flow">
71
- <http:listener config-ref="HTTPS_Listener" path="/orders/{orderId}"/>
72
- <flow-ref name="orders-proc-get-order-subflow"/>
73
- <ee:transform><!-- Channel-specific response format --></ee:transform>
74
- </flow>
75
-
76
- <!-- Process Layer: Orchestration -->
77
- <sub-flow name="orders-proc-get-order-subflow">
78
- <flow-ref name="orders-sys-get-order-subflow"/>
79
- <flow-ref name="customers-sys-get-customer-subflow"/>
80
- <!-- Aggregate data from multiple sources -->
81
- </sub-flow>
82
-
83
- <!-- System Layer: Database access -->
84
- <sub-flow name="orders-sys-get-order-subflow">
85
- <db:select config-ref="Database_Config">
86
- <db:sql>SELECT * FROM orders WHERE id = :orderId</db:sql>
87
- </db:select>
88
- </sub-flow>
89
- ```
90
-
91
- **Related Rules:** `API-001`, `API-002`, `API-003`
92
-
93
- ---
94
-
95
- ## Error Handling
96
-
97
- Proper error handling ensures consistent API responses and easier debugging.
98
-
99
- ### Key Principles
100
-
101
- 1. **Every flow needs error handling** - Either explicit or via global handler
102
- 2. **Set HTTP status codes** - Always set `httpStatus` variable for API responses
103
- 3. **Include correlation ID** - Enable distributed tracing
104
- 4. **Be specific about error types** - Avoid catching `type="ANY"`
105
-
106
- ### Global Error Handler Pattern
107
-
108
- Create a reusable global error handler:
109
-
110
- ```xml
111
- <!-- src/main/mule/global-error-handler.xml -->
112
- <error-handler name="global-error-handler">
113
- <on-error-propagate type="APIKIT:BAD_REQUEST">
114
- <set-variable variableName="httpStatus" value="400"/>
115
- <ee:transform>
116
- <ee:set-payload><![CDATA[%dw 2.0
117
- output application/json
118
- ---
119
- {
120
- correlationId: correlationId,
121
- error: "Bad Request",
122
- message: error.description
123
- }]]></ee:set-payload>
124
- </ee:transform>
125
- </on-error-propagate>
126
-
127
- <on-error-propagate type="APIKIT:NOT_FOUND">
128
- <set-variable variableName="httpStatus" value="404"/>
129
- <!-- ... -->
130
- </on-error-propagate>
131
-
132
- <!-- Catch-all for unexpected errors -->
133
- <on-error-propagate>
134
- <set-variable variableName="httpStatus" value="500"/>
135
- <logger category="com.myorg.errors" level="ERROR"
136
- message="#['Error: ' ++ error.description ++ ' | CorrelationId: ' ++ correlationId]"/>
137
- <!-- ... -->
138
- </on-error-propagate>
139
- </error-handler>
140
- ```
141
-
142
- ### Flow Error Handler Reference
143
-
144
- ```xml
145
- <flow name="my-api-flow">
146
- <http:listener config-ref="HTTPS_Listener" path="/resource"/>
147
- <!-- Flow logic -->
148
- <error-handler ref="global-error-handler"/>
149
- </flow>
150
- ```
151
-
152
- **Related Rules:** `MULE-001`, `MULE-003`, `MULE-005`, `MULE-007`, `MULE-009`
153
-
154
- ---
155
-
156
- ## Logging Standards
157
-
158
- Effective logging enables debugging and monitoring without compromising security or performance.
159
-
160
- ### Key Principles
161
-
162
- 1. **Always use categories** - Enable log filtering in production
163
- 2. **Never log full payloads** - May contain PII and cause performance issues
164
- 3. **Include correlation IDs** - Enable request tracing
165
- 4. **Use structured logging** - JSON format for log aggregation tools
166
-
167
- ### Logger Category Convention
168
-
169
- Use hierarchical category names:
170
-
171
- ```xml
172
- <!-- ✅ Good - Hierarchical categories -->
173
- <logger category="com.myorg.orders.api" level="INFO"
174
- message="#['Processing order: ' ++ vars.orderId]"/>
175
-
176
- <logger category="com.myorg.orders.db" level="DEBUG"
177
- message="#['Query executed in ' ++ vars.queryTime ++ 'ms']"/>
178
- ```
179
-
180
- ### Avoid Payload Logging
181
-
182
- ```xml
183
- <!-- ❌ Bad - Logs entire payload -->
184
- <logger message="#[payload]"/>
185
-
186
- <!-- ✅ Good - Logs specific fields -->
187
- <logger category="com.myorg.orders" level="INFO"
188
- message="#['Order ' ++ payload.orderId ++ ' received for customer ' ++ payload.customerId]"/>
189
- ```
190
-
191
- ### Structured Logging Format
192
-
193
- ```xml
194
- <logger category="com.myorg.audit" level="INFO">
195
- <message><![CDATA[#[%dw 2.0
196
- output application/json
197
- ---
198
- {
199
- correlationId: correlationId,
200
- event: "ORDER_CREATED",
201
- orderId: payload.orderId,
202
- timestamp: now()
203
- }]]]></message>
204
- </logger>
205
- ```
206
-
207
- ### Avoid Logging in Retry Loops
208
-
209
- ```xml
210
- <!-- ❌ Bad - Logger inside until-successful floods logs -->
211
- <until-successful maxRetries="5">
212
- <logger message="Attempting..."/> <!-- Will log 5 times on failure -->
213
- <http:request config-ref="HTTP_Config" path="/api"/>
214
- </until-successful>
215
-
216
- <!-- ✅ Good - Log before and after -->
217
- <logger category="com.myorg" message="Starting retry operation"/>
218
- <until-successful maxRetries="5">
219
- <http:request config-ref="HTTP_Config" path="/api"/>
220
- </until-successful>
221
- <logger category="com.myorg" message="Operation completed"/>
222
- ```
223
-
224
- **Related Rules:** `MULE-006`, `MULE-301`, `MULE-303`
225
-
226
- ---
227
-
228
- ## Security Guidelines
229
-
230
- Protect sensitive data and follow secure development practices.
231
-
232
- ### Never Hardcode Secrets
233
-
234
- ```xml
235
- <!-- ❌ Bad - Hardcoded credentials -->
236
- <http:request-config host="api.example.com"
237
- username="admin"
238
- password="secret123"/>
239
-
240
- <!-- ✅ Good - Property placeholders -->
241
- <http:request-config host="${api.host}"
242
- username="${api.username}"
243
- password="${secure::api.password}"/>
244
- ```
245
-
246
- ### Never Hardcode URLs
247
-
248
- ```xml
249
- <!-- ❌ Bad -->
250
- <http:request url="https://api.production.example.com/orders"/>
251
-
252
- <!-- ✅ Good -->
253
- <http:request url="${api.orders.baseUrl}/orders"/>
254
- ```
255
-
256
- ### Encrypt Sensitive Properties
257
-
258
- Use MuleSoft Secure Properties:
259
-
260
- ```yaml
261
- # secure.yaml (encrypted)
262
- api:
263
- password: '![encryptedValue]'
264
- clientSecret: '![encryptedValue]'
265
- ```
266
-
267
- ### TLS Configuration
268
-
269
- ```xml
270
- <!-- ❌ Bad - Insecure TLS -->
271
- <tls:context name="Insecure_TLS">
272
- <tls:trust-store insecure="true"/>
273
- </tls:context>
274
-
275
- <!-- ✅ Good - Proper certificate validation -->
276
- <tls:context name="Secure_TLS">
277
- <tls:trust-store path="${tls.truststore.path}"
278
- password="${secure::tls.truststore.password}"/>
279
- </tls:context>
280
- ```
281
-
282
- **Related Rules:** `MULE-004`, `MULE-201`, `MULE-202`, `YAML-004`
283
-
284
- ---
285
-
286
- ## Performance Patterns
287
-
288
- Avoid common performance anti-patterns.
289
-
290
- ### Async Scope Error Handling
291
-
292
- Async scopes don't propagate errors to parent flows:
293
-
294
- ```xml
295
- <!-- ❌ Bad - Errors silently swallowed -->
296
- <async>
297
- <http:request config-ref="HTTP_Config" path="/webhook"/>
298
- </async>
299
-
300
- <!-- ✅ Good - Explicit error handling -->
301
- <async>
302
- <try>
303
- <http:request config-ref="HTTP_Config" path="/webhook"/>
304
- <error-handler>
305
- <on-error-continue>
306
- <logger category="com.myorg.async" level="ERROR"
307
- message="#['Async failed: ' ++ error.description]"/>
308
- </on-error-continue>
309
- </error-handler>
310
- </try>
311
- </async>
312
- ```
313
-
314
- ### Limit Choice Complexity
315
-
316
- ```xml
317
- <!-- ❌ Bad - Too many when clauses -->
318
- <choice>
319
- <when expression="#[vars.status == 'NEW']">...</when>
320
- <when expression="#[vars.status == 'PENDING']">...</when>
321
- <when expression="#[vars.status == 'APPROVED']">...</when>
322
- <!-- 10+ more conditions -->
323
- <otherwise>...</otherwise>
324
- </choice>
325
-
326
- <!-- ✅ Good - Use DataWeave lookup -->
327
- <ee:transform>
328
- <ee:set-variable variableName="handler"><![CDATA[%dw 2.0
329
- var handlers = {
330
- "NEW": "new-handler-subflow",
331
- "PENDING": "pending-handler-subflow",
332
- "APPROVED": "approved-handler-subflow"
333
- }
334
- ---
335
- handlers[vars.status] default "default-handler-subflow"
336
- ]]></ee:set-variable>
337
- </ee:transform>
338
- <flow-ref name="#[vars.handler]"/>
339
- ```
340
-
341
- ### HTTP Timeout Configuration
342
-
343
- ```xml
344
- <!-- ✅ Always set explicit timeouts -->
345
- <http:request-config name="HTTP_Request_Config"
346
- responseTimeout="30000">
347
- <http:request-connection host="${api.host}"
348
- port="${api.port}"/>
349
- </http:request-config>
350
- ```
351
-
352
- ### Scatter-Gather Limits
353
-
354
- Limit parallel routes to avoid memory pressure:
355
-
356
- ```xml
357
- <!-- Keep scatter-gather routes manageable (< 5-7) -->
358
- <scatter-gather>
359
- <route><flow-ref name="service1-subflow"/></route>
360
- <route><flow-ref name="service2-subflow"/></route>
361
- <route><flow-ref name="service3-subflow"/></route>
362
- </scatter-gather>
363
- ```
364
-
365
- **Related Rules:** `MULE-403`, `MULE-501`, `MULE-502`, `MULE-503`, `MULE-801`
366
-
367
- ---
368
-
369
- ## Project Structure
370
-
371
- Follow standard MuleSoft project organization.
372
-
373
- ### Required Structure
374
-
375
- ```
376
- my-mule-project/
377
- ├── src/
378
- │ ├── main/
379
- │ │ ├── mule/ # Mule configuration files
380
- │ │ │ ├── global.xml # Shared configs (listeners, error handlers)
381
- │ │ │ ├── global-error-handler.xml
382
- │ │ │ ├── orders-api.xml # API implementation
383
- │ │ │ └── orders-flows.xml # Business flows
384
- │ │ └── resources/
385
- │ │ ├── api/ # RAML/OAS specifications
386
- │ │ ├── dwl/ # External DataWeave files
387
- │ │ │ ├── common.dwl # Reusable functions
388
- │ │ │ └── transform-order.dwl
389
- │ │ ├── dev.yaml # Environment configs
390
- │ │ ├── qa.yaml
391
- │ │ └── prod.yaml
392
- │ └── test/
393
- │ └── munit/ # MUnit test files
394
- ├── pom.xml
395
- └── mule-artifact.json
396
- ```
397
-
398
- ### File Organization Guidelines
399
-
400
- | Guideline | Recommendation |
401
- | ------------------- | ----------------------------------- |
402
- | Flows per file | Max 10 flows/sub-flows per XML file |
403
- | File responsibility | One domain/feature per file |
404
- | Global configs | Centralize in `global.xml` |
405
- | Error handling | Separate `global-error-handler.xml` |
406
-
407
- **Related Rules:** `MULE-802`, `MULE-803`, `MULE-804`
408
-
409
- ---
410
-
411
- ## Naming Conventions
412
-
413
- Consistent naming improves readability and maintainability.
414
-
415
- ### Flows and Sub-flows
416
-
417
- ```xml
418
- <!-- Use kebab-case with suffixes -->
419
- <flow name="orders-api-get-order-flow">
420
- <sub-flow name="validate-order-input-subflow">
421
- ```
422
-
423
- ### Variables
424
-
425
- ```xml
426
- <!-- Use camelCase -->
427
- <set-variable variableName="orderId"/>
428
- <set-variable variableName="customerData"/>
429
- ```
430
-
431
- ### Connector Configurations
432
-
433
- ```xml
434
- <!-- Use descriptive names -->
435
- <http:request-config name="Orders_API_Config"/>
436
- <db:config name="Orders_Database_Config"/>
437
- ```
438
-
439
- **Related Rules:** `MULE-002`, `MULE-101`, `MULE-102`, `EXP-002`
440
-
441
- ---
442
-
443
- ## Configuration Management
444
-
445
- Externalize environment-specific values.
446
-
447
- ### Environment Files
448
-
449
- Create separate files for each environment:
450
-
451
- ```yaml
452
- # dev.yaml
453
- http:
454
- host: '0.0.0.0'
455
- port: '8081'
456
-
457
- api:
458
- orders:
459
- baseUrl: 'http://localhost:8082/api'
460
- timeout: '30000'
461
-
462
- db:
463
- host: 'localhost'
464
- port: '5432'
465
- ```
466
-
467
- ### Property Naming
468
-
469
- Use hierarchical, lowercase naming:
470
-
471
- ```yaml
472
- # ✅ Good
473
- db.host: localhost
474
- api.orders.baseUrl: http://example.com
475
- http.request.timeout: 30000
476
-
477
- # ❌ Bad
478
- DBHOST: localhost
479
- ApiOrdersUrl: http://example.com
480
- HTTP_TIMEOUT: 30000
481
- ```
482
-
483
- **Related Rules:** `YAML-001`, `YAML-003`
484
-
485
- ---
486
-
487
- ## DataWeave Best Practices
488
-
489
- Write maintainable and reusable DataWeave code.
490
-
491
- ### Externalize Complex Transforms
492
-
493
- ```xml
494
- <!-- ❌ Bad - Large inline transform -->
495
- <ee:transform>
496
- <ee:set-payload><![CDATA[%dw 2.0
497
- <!-- 50+ lines of DataWeave -->
498
- ]]></ee:set-payload>
499
- </ee:transform>
500
-
501
- <!-- ✅ Good - External file -->
502
- <ee:transform>
503
- <ee:set-payload resource="dwl/transform-order-response.dwl"/>
504
- </ee:transform>
505
- ```
506
-
507
- ### Create Reusable Modules
508
-
509
- ```dataweave
510
- // src/main/resources/dwl/common.dwl
511
- %dw 2.0
512
-
513
- fun formatDate(date: DateTime) =
514
- date as String {format: "yyyy-MM-dd"}
515
-
516
- fun maskPII(value: String) =
517
- value[0 to 2] ++ "****" ++ value[-2 to -1]
518
-
519
- fun toErrorResponse(error, correlationId: String) = {
520
- correlationId: correlationId,
521
- timestamp: now(),
522
- error: error.errorType.identifier,
523
- message: error.description
524
- }
525
- ```
526
-
527
- ### File Naming
528
-
529
- Use kebab-case for DWL files:
530
-
531
- - `transform-order.dwl`
532
- - `validate-input.dwl`
533
- - `common-utils.dwl`
534
-
535
- **Related Rules:** `DW-001`, `DW-002`, `DW-003`
536
-
537
- ---
538
-
539
- ## Documentation Standards
540
-
541
- Document for maintainability.
542
-
543
- ### Flow Documentation
544
-
545
- ```xml
546
- <flow name="orders-api-create-order-flow"
547
- doc:name="Create Order"
548
- doc:description="Creates a new order in the system. Validates input, checks inventory, and persists to database.">
549
- ```
550
-
551
- ### Component Documentation
552
-
553
- ```xml
554
- <logger doc:name="Log Order Received"
555
- category="com.myorg.orders"
556
- message="#['Order received: ' ++ payload.orderId]"/>
557
-
558
- <ee:transform doc:name="Transform to Database Format">
559
- <!-- ... -->
560
- </ee:transform>
561
- ```
562
-
563
- **Related Rules:** `MULE-601`, `MULE-604`
564
-
565
- ---
566
-
567
- ## Quick Reference Card
568
-
569
- | Practice | Do | Don't |
570
- | ------------------ | ------------------------------------- | ------------------------------------- |
571
- | **Error Handling** | Use global handler, set httpStatus | Catch `type="ANY"`, ignore errors |
572
- | **Logging** | Use categories, log specific fields | Log `#[payload]`, log in retry loops |
573
- | **Security** | Use `${property}`, encrypt secrets | Hardcode URLs, passwords, keys |
574
- | **Performance** | Set timeouts, handle async errors | Unlimited retries, huge choice blocks |
575
- | **Naming** | kebab-case flows, camelCase vars | Inconsistent casing, no suffixes |
576
- | **Structure** | Separate files by domain | Monolithic XML files |
577
- | **Config** | Environment-specific YAML files | Hardcoded values |
578
- | **DataWeave** | External .dwl files, reusable modules | Large inline transforms |
579
-
580
- ---
581
-
582
- # General Developer Guidelines
583
-
584
- > The following sections cover general MuleSoft development best practices that are not enforced by the linter but are important for building production-ready applications.
585
-
586
- ---
587
-
588
- ## Testing with MUnit
589
-
590
- MUnit is MuleSoft's native testing framework. Comprehensive testing is essential for reliable integrations.
591
-
592
- ### Test Coverage Goals
593
-
594
- | Test Type | Coverage Target | Purpose |
595
- | -------------------- | ------------------ | ------------------------------ |
596
- | Unit Tests | 80%+ flow coverage | Validate individual flow logic |
597
- | Integration Tests | All critical paths | Validate end-to-end scenarios |
598
- | Error Scenario Tests | All error handlers | Validate error responses |
599
-
600
- ### MUnit Best Practices
601
-
602
- ```xml
603
- <!-- test/munit/orders-api-test-suite.xml -->
604
- <munit:test name="create-order-success-test"
605
- description="Validates successful order creation">
606
-
607
- <!-- Mock external dependencies -->
608
- <munit:behavior>
609
- <munit-tools:mock-when processor="http:request">
610
- <munit-tools:with-attributes>
611
- <munit-tools:with-attribute attributeName="config-ref"
612
- whereValue="Orders_HTTP_Config"/>
613
- </munit-tools:with-attributes>
614
- <munit-tools:then-return>
615
- <munit-tools:payload value='{"orderId": "12345"}'/>
616
- </munit-tools:then-return>
617
- </munit-tools:mock-when>
618
- </munit:behavior>
619
-
620
- <!-- Execute -->
621
- <munit:execution>
622
- <flow-ref name="create-order-flow"/>
623
- </munit:execution>
624
-
625
- <!-- Assert -->
626
- <munit:validation>
627
- <munit-tools:assert-that expression="#[payload.orderId]"
628
- is="#[MunitTools::notNullValue()]"/>
629
- </munit:validation>
630
- </munit:test>
631
- ```
632
-
633
- ### Test Organization
634
-
635
- ```
636
- src/test/munit/
637
- ├── orders-api-test-suite.xml # API endpoint tests
638
- ├── orders-flows-test-suite.xml # Business logic tests
639
- ├── error-handling-test-suite.xml # Error scenario tests
640
- └── common-test-resources.xml # Shared mocks and utilities
641
- ```
642
-
643
- ### Key Principles
644
-
645
- 1. **Mock external dependencies** - Don't call real systems in unit tests
646
- 2. **Test error scenarios** - Verify all error handlers work correctly
647
- 3. **Use descriptive test names** - Names should describe the scenario
648
- 4. **Isolate tests** - Each test should be independent
649
-
650
- ---
651
-
652
- ## CI/CD Integration
653
-
654
- Automate build, test, and deployment for consistent, reliable releases.
655
-
656
- ### Recommended Pipeline Stages
657
-
658
- ```
659
- ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
660
- │ Build │ → │ Lint │ → │ Test │ → │ Package │ → │ Deploy │
661
- │ │ │ │ │ │ │ │ │ │
662
- │ mvn │ │ mule- │ │ mvn test │ │ mvn │ │ anypoint │
663
- │ compile │ │ lint │ │ │ │ package │ │ deploy │
664
- └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘
665
- ```
666
-
667
- ### GitHub Actions Example
668
-
669
- ```yaml
670
- # .github/workflows/mule-ci.yml
671
- name: Mule CI/CD
672
-
673
- on:
674
- push:
675
- branches: [main, develop]
676
- pull_request:
677
- branches: [main]
678
-
679
- jobs:
680
- build-and-test:
681
- runs-on: ubuntu-latest
682
- steps:
683
- - uses: actions/checkout@v4
684
-
685
- - name: Set up JDK 11
686
- uses: actions/setup-java@v3
687
- with:
688
- java-version: '11'
689
- distribution: 'adopt'
690
-
691
- - name: Cache Maven packages
692
- uses: actions/cache@v3
693
- with:
694
- path: ~/.m2
695
- key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
696
-
697
- - name: Build with Maven
698
- run: mvn -B clean compile
699
-
700
- - name: Run mule-lint
701
- run: npx @sfdxy/mule-lint ./src/main/mule -f sarif -o lint-results.sarif
702
-
703
- - name: Run MUnit tests
704
- run: mvn -B test
705
-
706
- - name: Upload SARIF results
707
- uses: github/codeql-action/upload-sarif@v2
708
- with:
709
- sarif_file: lint-results.sarif
710
- ```
711
-
712
- ### Git Branch Strategy
713
-
714
- | Branch | Purpose | Deployment Target |
715
- | ----------- | --------------------- | ----------------- |
716
- | `main` | Production-ready code | Production |
717
- | `develop` | Integration branch | QA/Staging |
718
- | `feature/*` | New features | Development |
719
- | `hotfix/*` | Production fixes | Production |
720
-
721
- ---
722
-
723
- ## API Versioning
724
-
725
- Plan for API evolution from the start.
726
-
727
- ### URL-Based Versioning (Recommended)
728
-
729
- ```
730
- /api/v1/orders
731
- /api/v2/orders
732
- ```
733
-
734
- ### Implementation Pattern
735
-
736
- ```xml
737
- <!-- src/main/mule/orders-api-v1.xml -->
738
- <flow name="orders-api-v1-main-flow">
739
- <http:listener config-ref="HTTPS_Listener" path="/api/v1/orders/*"/>
740
- <apikit:router config-ref="orders-v1-config"/>
741
- </flow>
742
-
743
- <!-- src/main/mule/orders-api-v2.xml -->
744
- <flow name="orders-api-v2-main-flow">
745
- <http:listener config-ref="HTTPS_Listener" path="/api/v2/orders/*"/>
746
- <apikit:router config-ref="orders-v2-config"/>
747
- </flow>
748
- ```
749
-
750
- ### Version Deprecation Strategy
751
-
752
- 1. **Announce deprecation** - Communicate timeline to consumers
753
- 2. **Add deprecation headers** - Return `Deprecation` header in responses
754
- 3. **Monitor usage** - Track v1 vs v2 adoption
755
- 4. **Sunset gracefully** - Remove only after consumer migration
756
-
757
- ```xml
758
- <!-- Add deprecation warning -->
759
- <set-variable variableName="outboundHeaders" value="#[{
760
- 'Deprecation': 'true',
761
- 'Sunset': 'Sat, 01 Jan 2025 00:00:00 GMT',
762
- 'Link': '&lt;/api/v2/orders&gt;; rel="successor-version"'
763
- }]"/>
764
- ```
765
-
766
- ---
767
-
768
- ## Deployment Practices
769
-
770
- Deploy safely and consistently across environments.
771
-
772
- ### Environment Promotion
773
-
774
- ```
775
- Development → QA → Staging → Production
776
- ↓ ↓ ↓ ↓
777
- dev.yaml qa.yaml stg.yaml prod.yaml
778
- ```
779
-
780
- ### Deployment Checklist
781
-
782
- | Item | Description |
783
- | ------------------------ | ----------------------------- |
784
- | ✅ All tests pass | MUnit and integration tests |
785
- | ✅ Lint checks pass | No errors from mule-lint |
786
- | ✅ Properties configured | Environment YAML verified |
787
- | ✅ Secrets encrypted | No plaintext credentials |
788
- | ✅ API Manager policies | Authentication, rate limiting |
789
- | ✅ Monitoring configured | Dashboards and alerts ready |
790
-
791
- ### Blue-Green Deployment
792
-
793
- For zero-downtime deployments:
794
-
795
- 1. Deploy new version to "green" workers
796
- 2. Run smoke tests against green
797
- 3. Switch load balancer to green
798
- 4. Monitor for issues
799
- 5. Decommission "blue" workers (or keep for rollback)
800
-
801
- ### Rollback Strategy
802
-
803
- ```bash
804
- # Anypoint CLI rollback example
805
- anypoint-cli runtime-mgr cloudhub-application modify \
806
- --environment Production \
807
- --applicationName orders-api \
808
- --runtime 4.4.0 \
809
- --artifact-id orders-api-1.2.0.jar
810
- ```
82
+ | Layer | Should Have | Should NOT Have |
83
+ | -------------- | -------------------------------------------------- | ---------------------------------------------- |
84
+ | **Experience** | HTTP listeners, channel-specific transforms | Direct database access, complex business logic |
85
+ | **Process** | Flow-refs to SAPIs, orchestration, event listeners | Direct system connections |
86
+ | **System** | Connector operations, entity CRUD | Business logic, data aggregation |
811
87
 
812
88
  ---
813
89
 
814
- ## Monitoring and Observability
815
-
816
- Production applications need comprehensive monitoring.
817
-
818
- ### The Three Pillars
819
-
820
- | Pillar | Tool | Purpose |
821
- | ----------- | -------------------------------- | ------------------------------ |
822
- | **Logs** | Anypoint Monitoring, Splunk, ELK | Debug issues, audit trail |
823
- | **Metrics** | Anypoint Monitoring, Grafana | Performance, health status |
824
- | **Traces** | Anypoint Monitoring, Jaeger | Request flow, latency analysis |
825
-
826
- ### Key Metrics to Monitor
827
-
828
- ```
829
- Application Health:
830
- ├── Response time (p50, p95, p99)
831
- ├── Error rate (%)
832
- ├── Throughput (requests/sec)
833
- ├── Active connections
834
- └── Worker CPU/Memory usage
835
-
836
- Business Metrics:
837
- ├── Orders processed per hour
838
- ├── Failed transactions
839
- ├── API calls by consumer
840
- └── Integration latency by backend
841
- ```
842
-
843
- ### Alerting Best Practices
844
-
845
- | Alert Level | Condition | Response |
846
- | ------------ | -------------------------------- | -------------------------- |
847
- | **Critical** | Error rate > 10%, App down | Immediate on-call response |
848
- | **Warning** | Error rate > 5%, Latency > 5s | Investigate within 1 hour |
849
- | **Info** | Unusual patterns, Resource > 70% | Review in daily standup |
90
+ ## For AI Agents (MCP)
850
91
 
851
- ### Correlation ID Pattern
92
+ These best practice guides are exposed via the MuleSoft Lint MCP server as individual resources. AI agents can request specific topics:
852
93
 
853
- Ensure correlation IDs flow through all systems:
854
-
855
- ```xml
856
- <!-- Set correlation ID at entry point -->
857
- <set-variable variableName="correlationId"
858
- value="#[correlationId default uuid()]"/>
859
-
860
- <!-- Include in all outbound requests -->
861
- <http:request config-ref="HTTP_Config" path="/downstream">
862
- <http:headers><![CDATA[#[{
863
- 'X-Correlation-ID': vars.correlationId
864
- }]]]></http:headers>
865
- </http:request>
866
-
867
- <!-- Include in all log messages -->
868
- <logger category="com.myorg"
869
- message="#['[' ++ vars.correlationId ++ '] Processing request...']"/>
870
94
  ```
871
-
872
- ### Health Check Endpoint
873
-
874
- Expose a health endpoint for load balancers and monitoring:
875
-
876
- ```xml
877
- <flow name="health-check-flow">
878
- <http:listener config-ref="HTTPS_Listener" path="/health"/>
879
- <set-payload value='#[%dw 2.0
880
- output application/json
881
- ---
882
- {
883
- status: "UP",
884
- timestamp: now(),
885
- version: p("app.version"),
886
- environment: p("mule.env")
887
- }]'/>
888
- </flow>
95
+ mule-lint://docs/error-handling → Error handling guidance
96
+ mule-lint://docs/event-driven → Event-driven patterns
97
+ mule-lint://docs/connectors → Connector configuration
98
+ mule-lint://docs/variables → Variable contracts
99
+ mule-lint://docs/dataweave → DataWeave patterns
100
+ mule-lint://docs/security → Security best practices
101
+ mule-lint://docs/logging → Logging standards
102
+ mule-lint://docs/performance → Performance optimization
103
+ mule-lint://docs/testing → MUnit testing
104
+ mule-lint://docs/deployment → Deployment & modernization
105
+ mule-lint://docs/ci-cd → CI/CD integration
106
+ mule-lint://docs/folder-structure → Project structure
107
+ mule-lint://docs/documentation-standards → Documentation standards
108
+ mule-lint://docs/rules-catalog → Complete rules reference
889
109
  ```
890
110
 
891
- ---
892
-
893
- ## Summary
894
-
895
- This guide covers both linter-enforced practices and general developer guidelines:
896
-
897
- | Category | Linter Enforced | General Guidelines |
898
- | ------------ | -------------------------------- | ----------------------------- |
899
- | Code Quality | ✅ Naming, Structure, Complexity | Testing, Code Review |
900
- | Security | ✅ Hardcoded secrets, TLS | Secrets Management, IAM |
901
- | Operations | ✅ Error handling, Logging | CI/CD, Monitoring, Deployment |
902
- | Architecture | ✅ API-Led patterns | Versioning, Documentation |
903
-
904
111
  For linter rule details, see the [Rules Catalog](rules-catalog.md).