mirror of
https://github.com/forcedotcom/afv-library.git
synced 2026-08-05 23:41:31 +08:00
214 lines
6.2 KiB
Markdown
214 lines
6.2 KiB
Markdown
# WSDL to Apex Generation Guide
|
|
|
|
## Overview
|
|
|
|
Salesforce can automatically generate Apex classes from WSDL (Web Services Description Language) files, enabling integration with SOAP-based web services.
|
|
|
|
## Step-by-Step Process
|
|
|
|
### 1. Obtain the WSDL File
|
|
|
|
Get the WSDL from your external system. Common sources:
|
|
- API documentation portal
|
|
- Endpoint URL with `?wsdl` suffix (e.g., `https://api.example.com/service?wsdl`)
|
|
- Direct download from vendor
|
|
|
|
### 2. Review WSDL for Compatibility
|
|
|
|
Salesforce WSDL2Apex has limitations. Check for:
|
|
|
|
**Supported:**
|
|
- Document/literal and RPC/encoded styles
|
|
- Simple types (string, integer, boolean, date, etc.)
|
|
- Complex types (objects with properties)
|
|
- Arrays and lists
|
|
- Basic SOAP headers
|
|
|
|
**Not Supported / Problematic:**
|
|
- Very large WSDLs (may hit Apex class size limits)
|
|
- Certain complex inheritance patterns
|
|
- Some advanced XSD features
|
|
- WS-Security (requires manual implementation)
|
|
|
|
### 3. Generate Apex Classes
|
|
|
|
1. Navigate to **Setup → Apex Classes**
|
|
2. Click **Generate from WSDL**
|
|
3. Click **Choose File** and upload the WSDL
|
|
4. Review the parse results
|
|
5. Modify class names if needed (keep them short to avoid limits)
|
|
6. Click **Generate Apex code**
|
|
|
|
### 4. Generated Class Structure
|
|
|
|
For a WSDL defining `CustomerService` with operation `getCustomer`:
|
|
|
|
```
|
|
AsyncCustomerService.cls - Async version of service
|
|
CustomerService.cls - Main stub class with methods
|
|
GetCustomerRequest.cls - Request wrapper
|
|
GetCustomerResponse.cls - Response wrapper
|
|
Customer.cls - Data type from schema
|
|
Address.cls - Nested data type
|
|
```
|
|
|
|
### 5. Configure Endpoint Access
|
|
|
|
**Option A: Named Credential (Recommended)**
|
|
|
|
1. Create Named Credential in Setup
|
|
2. Set endpoint to SOAP service URL
|
|
3. Configure authentication (Basic, Certificate, OAuth)
|
|
4. In Apex: `stub.endpoint_x = 'callout:MyNamedCredential';`
|
|
|
|
**Option B: Remote Site Setting**
|
|
|
|
1. Create Remote Site Setting with domain
|
|
2. In Apex: `stub.endpoint_x = 'https://api.example.com/service';`
|
|
|
|
### 6. Basic Usage Example
|
|
|
|
```apex
|
|
public class CustomerServiceCaller {
|
|
|
|
public static Customer getCustomer(String customerId) {
|
|
// Instantiate the generated stub
|
|
CustomerService.CustomerServicePort stub = new CustomerService.CustomerServicePort();
|
|
|
|
// Configure endpoint (Named Credential)
|
|
stub.endpoint_x = 'callout:CustomerServiceNC';
|
|
|
|
// Set timeout (max 120 seconds)
|
|
stub.timeout_x = 120000;
|
|
|
|
// Create request
|
|
GetCustomerRequest request = new GetCustomerRequest();
|
|
request.customerId = customerId;
|
|
|
|
// Make the call
|
|
GetCustomerResponse response = stub.getCustomer(request);
|
|
|
|
return response.customer;
|
|
}
|
|
}
|
|
```
|
|
|
|
### 7. Error Handling
|
|
|
|
```apex
|
|
try {
|
|
GetCustomerResponse response = stub.getCustomer(request);
|
|
// Process response
|
|
|
|
} catch (CalloutException e) {
|
|
// Network error, timeout, SSL issues
|
|
System.debug('Callout failed: ' + e.getMessage());
|
|
|
|
} catch (Exception e) {
|
|
// SOAP fault (error from service)
|
|
// The exception message contains SOAP fault details
|
|
System.debug('SOAP error: ' + e.getMessage());
|
|
}
|
|
```
|
|
|
|
### 8. Common Issues and Solutions
|
|
|
|
| Issue | Cause | Solution |
|
|
|-------|-------|----------|
|
|
| `Web service callout failed` | Network/SSL issue | Check Remote Site Setting, verify endpoint |
|
|
| `Read timed out` | Service slow to respond | Increase `timeout_x` (max 120000ms) |
|
|
| `Apex class size limit` | WSDL too large | Split WSDL, use fewer operations |
|
|
| `Unable to parse callout response` | Response doesn't match WSDL | Check service version, update WSDL |
|
|
| `Methods defined as Webservice` | Conflict with reserved keywords | Rename operations in WSDL or generated class |
|
|
|
|
### 9. Testing SOAP Callouts
|
|
|
|
Use `Test.setMock()` with `WebServiceMock`:
|
|
|
|
```apex
|
|
@isTest
|
|
public class CustomerServiceTest {
|
|
|
|
@isTest
|
|
static void testGetCustomer() {
|
|
// Set mock
|
|
Test.setMock(WebServiceMock.class, new CustomerServiceMock());
|
|
|
|
// Call service
|
|
Test.startTest();
|
|
Customer result = CustomerServiceCaller.getCustomer('CUST001');
|
|
Test.stopTest();
|
|
|
|
// Assert
|
|
System.assertEquals('Test Customer', result.name);
|
|
}
|
|
|
|
// Mock implementation
|
|
public class CustomerServiceMock implements WebServiceMock {
|
|
public void doInvoke(
|
|
Object stub,
|
|
Object request,
|
|
Map<String, Object> response,
|
|
String endpoint,
|
|
String soapAction,
|
|
String requestName,
|
|
String responseNS,
|
|
String responseName,
|
|
String responseType
|
|
) {
|
|
// Create mock response
|
|
GetCustomerResponse mockResponse = new GetCustomerResponse();
|
|
mockResponse.customer = new Customer();
|
|
mockResponse.customer.name = 'Test Customer';
|
|
|
|
response.put('response_x', mockResponse);
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### 10. Async SOAP Calls
|
|
|
|
For calls from triggers or after DML:
|
|
|
|
```apex
|
|
public class CustomerSyncQueueable implements Queueable, Database.AllowsCallouts {
|
|
|
|
private String customerId;
|
|
|
|
public CustomerSyncQueueable(String customerId) {
|
|
this.customerId = customerId;
|
|
}
|
|
|
|
public void execute(QueueableContext context) {
|
|
try {
|
|
Customer customer = CustomerServiceCaller.getCustomer(customerId);
|
|
// Process result
|
|
} catch (Exception e) {
|
|
// Log error
|
|
}
|
|
}
|
|
}
|
|
|
|
// Usage in trigger:
|
|
System.enqueueJob(new CustomerSyncQueueable(accountId));
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
1. **Always use Named Credentials** for authentication instead of hardcoding credentials
|
|
2. **Set appropriate timeouts** - default may be too short
|
|
3. **Implement error handling** - SOAP services can fail in many ways
|
|
4. **Log requests and responses** for debugging
|
|
5. **Use async patterns** when calling from DML contexts
|
|
6. **Test with mocks** - don't call real services in tests
|
|
7. **Monitor governor limits** - especially for large responses
|
|
|
|
## Limitations
|
|
|
|
- Maximum 100 callouts per transaction
|
|
- Maximum 120 second timeout per callout
|
|
- Response body limit: 6MB
|
|
- Apex code size limits may prevent large WSDL imports
|
|
- Some WSDL features not supported (WS-Security, MTOM, etc.)
|