@HttpPost Apex REST web service allows outside applications to send JSON data directly into Salesforce. The server parses the incoming request payload, processes the data, and sends back a structured JSON response.
Building custom web services in Salesforce allows external systems to interact with your org seamlessly. Using the @RestResource annotation alongside @HttpPost, you can easily expose Apex classes as custom REST API endpoints to accept incoming JSON payloads and return dynamic responses.
Apex @HttpPost Web Service Implementation
Here is clean, production-ready Apex code for an @HttpPost REST web service in Salesforce. It accepts raw JSON input, processes the data using untyped deserialization, and returns a JSON confirmation message back to the caller.
@RestResource(urlMapping='/myservice')
global with sharing class MyRestService {
@HttpPost
global static String doPost(String requestBody) {
try {
// Parse the incoming JSON request body dynamically
Map<String, Object> requestMap = (Map<String, Object>) JSON.deserializeUntyped(requestBody);
// Extract attributes from the request payload
String firstName = (String) requestMap.get('firstName');
String lastName = (String) requestMap.get('lastName');
Integer age = (Integer) requestMap.get('age');
// Build the response Map
Map<String, Object> responseMap = new Map<String, Object>();
responseMap.put('message', 'Data received successfully');
responseMap.put('firstName', firstName);
responseMap.put('lastName', lastName);
responseMap.put('age', age);
// Serialize response Map to JSON string
return JSON.serialize(responseMap);
} catch (Exception e) {
// Gracefully handle runtime errors and return an error payload
Map<String, Object> errorResponse = new Map<String, Object>();
errorResponse.put('error', 'An error occurred: ' + e.getMessage());
return JSON.serialize(errorResponse);
}
}
}
When an external application sends an HTTP POST request to /services/apexrest/myservice with a JSON payload like {"firstName": "John", "lastName": "Doe", "age": 30}, Salesforce routes the body directly into the requestBody parameter for processing.
JSON.deserializeUntyped(), numeric values like age can sometimes be deserialized as Decimal instead of Integer depending on formatting. Direct explicit casting without null-checks or type validation can throw a runtime System.TypeException.
- Rule: Annotate your class with
@RestResourceand expose the method using@HttpPost. - Gain: Enables custom real-time inbound integrations from external servers directly into Salesforce database logic.
- Price: External clients must authenticate via OAuth 2.0 (Bearer Token) before making requests.
- Limits: REST responses must stay within standard Apex heap size and execution governor limits.
Key Architectural Takeaways
- URL Mapping: The
@RestResource(urlMapping='/myservice')annotation exposes the endpoint at/services/apexrest/myservicerelative to your Salesforce instance domain. - HTTP Method Mapping: The
@HttpPostannotation tells Salesforce to execute this static method whenever an inbound HTTP POST request hits the endpoint URL. - Dynamic Parsing: Taking
String requestBodyas a parameter allows developers to dynamically parse incoming payloads usingJSON.deserializeUntyped()without requiring rigid wrapper classes. - Structured Error Handling: Wrapping logic inside a
try-catchblock ensures that exception messages are safely serialized into JSON and returned gracefully instead of throwing unhandled 500 server errors.