Apex REST supports two formats for representations of resources: JSON and XML. JSON representations are passed by default in the body of a request or response, and the format is indicated by the Content-Type property in the HTTP header. You can retrieve the body as a Blob from the HttpRequest object if there are no parameters to the Apex method. If parameters are defined in the Apex method, an attempt is made to deserialize the request body into those parameters. If the Apex method has a non-void return type, the resource representation is serialized into the response body.
These return and parameter types are allowed:
Methods annotated with @HttpGet or @HttpDelete should have no parameters. This is because GET and DELETE requests have no request body, so there's nothing to deserialize.
A single Apex class annotated with @RestResource can't have multiple methods annotated with the same HTTP request method. For example, the same class can't have two methods annotated with @HttpGet.
RestRequest req = RestContext.request; RestResponse res = RestContext.response;
You can use user-defined types for parameters in your Apex REST methods. Apex REST deserializes request data into public, private, or global class member variables of the user-defined type, unless the variable is declared as static or transient. For example, an Apex REST method that contains a user-defined type parameter might look like the following:
@RestResource(urlMapping='/user_defined_type_example/*') global with sharing class MyOwnTypeRestResource { @HttpPost global static MyUserDefinedClass echoMyType(MyUserDefinedClass ic) { return ic; } global class MyUserDefinedClass { global String string1; global String string2 { get; set; } private String privateString; global transient String transientString; global static String staticString; } }
Valid JSON and XML request data for this method would look like:
{ "ic" : { "string1" : "value for string1", "string2" : "value for string2", "privateString" : "value for privateString" } }
<request> <ic> <string1>value for string1</string1> <string2>value for string2</string2> <privateString>value for privateString</privateString> </ic> </request>
@RestResource(urlMapping='/CycleExample/*') global with sharing class ApexRESTCycleExample { @HttpGet global static MyUserDef1 doCycleTest() { MyUserDef1 def1 = new MyUserDef1(); MyUserDef2 def2 = new MyUserDef2(); def1.userDef2 = def2; def2.userDef1 = def1; return def1; } global class MyUserDef1 { MyUserDef2 userDef2; } global class MyUserDef2 { MyUserDef1 userDef1; } }
@HttpPost global static void myPostMethod(String s1, Integer i1, Boolean b1, String s2)
{ "s1" : "my first string", "i1" : 123, "s2" : "my second string", "b1" : false }
<request> <s1>my first string</s1> <i1>123</i1> <s2>my second string</s2> <b1>false</b1> </request>
{ "x" : "value1", "x" : "value2" }
@RestResource(urlMapping='/DuplicateParamsExample/*') global with sharing class ApexRESTDuplicateParamsExample { @HttpPost global static MyUserDef1 doDuplicateParamsTest(MyUserDef1 def) { return def; } global class MyUserDef1 { Integer i; } }
{ "def" : { "i" : 1, "i" : 2 } }
@RestResource(urlMapping='/namespaceExample/*') global class MyNamespaceTest { @HttpPost global static MyUDT echoTest(MyUDT def, String extraString) { return def; } global class MyUDT { Integer count; } }
<request> <def xmlns:MyUDT="http://soap.sforce.com/schemas/class/MyNamespaceTest"> <MyUDT:count>23</MyUDT:count> </def> <extraString>test</extraString> </request>
The status code of a response is set automatically. This table lists some HTTP status codes and what they mean in the context of the HTTP request method. For the full list of response status codes, see statusCode.
Request Method | Response Status Code | Description |
---|---|---|
GET | 200 | The request was successful. |
PATCH | 200 | The request was successful and the return type is non-void. |
PATCH | 204 | The request was successful and the return type is void. |
DELETE, GET, PATCH, POST, PUT | 400 | An unhandled user exception occurred. |
DELETE, GET, PATCH, POST, PUT | 403 | You don't have access to the specified Apex class. |
DELETE, GET, PATCH, POST, PUT | 404 | The URL is unmapped in an existing @RestResource annotation. |
DELETE, GET, PATCH, POST, PUT | 404 | The URL extension is unsupported. |
DELETE, GET, PATCH, POST, PUT | 404 | The Apex class with the specified namespace couldn't be found. |
DELETE, GET, PATCH, POST, PUT | 405 | The request method doesn't have a corresponding Apex method. |
DELETE, GET, PATCH, POST, PUT | 406 | The Content-Type property in the header was set to a value other than JSON or XML. |
DELETE, GET, PATCH, POST, PUT | 406 | The header specified in the HTTP request is not supported. |
GET, PATCH, POST, PUT | 406 | The XML return type specified for format is unsupported. |
DELETE, GET, PATCH, POST, PUT | 415 | The XML parameter type is unsupported. |
DELETE, GET, PATCH, POST, PUT | 415 | The Content-Header Type specified in the HTTP request header is unsupported. |
DELETE, GET, PATCH, POST, PUT | 500 | An unhandled Apex exception occurred. |