SOAP is an XML-based, strongly-typed protocol with a WSDL contract describing every method, input, and output. You generate a stub from the WSDL in your client language. Heavy, but provides strong contract guarantees.
REST is an HTTP-based, JSON-friendly architectural style. Resources are URLs, verbs are HTTP methods (GET/POST/PATCH/DELETE), payloads are typically JSON. Lighter, more flexible, easier to consume from any language.
Apex Web Services are how you expose Apex code as a callable web service. Two flavours:
Apex SOAP Web Services (older):
apex global class MyService { webservice static String getThing(Id recordId) { ... } }
Annotated webservice methods generate WSDL. Clients consume by importing the WSDL.
Apex REST Services (modern):
apex @RestResource(urlMapping='/things/*') global class ThingService { @HttpGet global static Thing doGet() { ... } @HttpPost global static String doPost(String name) { ... } }
URL-routed, HTTP-verb-based, JSON automatically marshalled.
When to use which:
- Calling Salesforce from external — generally pick REST. Less ceremony, modern tooling, broad client support.
- Building Apex services for external consumption — Apex REST. SOAP is largely legacy.
- Calling external services from Apex (callout) — REST callout via
Http/HttpRequest/HttpResponse. SOAP callouts work but are heavier. - Legacy systems mandating SOAP — fall back to Apex SOAP. Increasingly rare.
Authentication:
- OAuth — preferred. Connected App + chosen flow.
- Username/Password OAuth flow — legacy, generally discouraged.
- JWT Bearer flow — for server-to-server with no user.
- Session ID — accept Salesforce's session cookie for in-platform calls.
Governor limits apply to web service Apex too — your endpoint must stay under SOQL/CPU/heap limits per request. Plan accordingly.
Modern guidance: for new integrations, use Apex REST + OAuth. SOAP is a maintenance burden you carry only for compatibility.
