Tag Archives: Apex

Limit Class and Limit Methods in Salesforce

The Limits methods return the specific limit for the particular governor, such as the number of calls of a method or the amount of heap size remaining.

Because Apex runs in a multitenant environment, the Apex runtime engine strictly enforces a number of limits to ensure that runaway Apex doesn’t monopolize shared resources.

None of the Limits methods require an argument. The format of the limits methods is as follows:

 Integer queryLimitRows = Limits.getLimitQueryRows();

There are two versions of every method: the first returns the amount of the resource that has been used while the second version contains the word limit and returns the total amount of the resource that is available.

Limits Methods:
The following are methods for Limits. All methods are static.

System.debug('Limits.getAggregateQueries - '+ Limits.getAggregateQueries());
System.debug('Limits.getLimitAggregateQueries - '+ Limits.getLimitAggregateQueries());
System.debug('Limits.getCallouts - '+ Limits.getCallouts());
System.debug('Limits.getLimitCallouts - '+ Limits.getLimitCallouts());
System.debug('Limits.getCpuTime - '+ Limits.getCpuTime());
System.debug('Limits.getLimitCpuTime - '+ Limits.getLimitCpuTime());
System.debug('Limits.getDMLRows - '+ Limits.getDMLRows());
System.debug('Limits.getLimitDMLRows - '+ Limits.getLimitDMLRows());
System.debug('Limits.getDMLStatements - '+ Limits.getDMLStatements());
System.debug('Limits.getLimitDMLStatements - '+ Limits.getLimitDMLStatements());
System.debug('Limits.getEmailInvocations - '+ Limits.getEmailInvocations());
System.debug('Limits.getLimitEmailInvocations - '+ Limits.getLimitEmailInvocations());
System.debug('Limits.getFutureCalls - '+ Limits.getFutureCalls());
System.debug('Limits.getLimitFutureCalls - '+ Limits.getLimitFutureCalls());
System.debug('Limits.getHeapSize - '+ Limits.getHeapSize());
System.debug('Limits.getLimitHeapSize - '+ Limits.getLimitHeapSize());
System.debug('Limits.getMobilePushApexCalls - '+ Limits.getMobilePushApexCalls());
System.debug('Limits.getLimitMobilePushApexCalls - '+ Limits.getLimitMobilePushApexCalls());
System.debug('Limits.getQueries - '+ Limits.getQueries());
System.debug('Limits.getLimitQueries - '+ Limits.getLimitQueries());
System.debug('Limits.getQueryLocatorRows - '+ Limits.getQueryLocatorRows());
System.debug('Limits.getLimitQueryLocatorRows - '+ Limits.getLimitQueryLocatorRows());
System.debug('Limits.getQueryRows - '+ Limits.getQueryRows());
System.debug('Limits.getLimitQueryRows - '+ Limits.getLimitQueryRows());
System.debug('Limits.getQueueableJobs - '+ Limits.getQueueableJobs());
System.debug('Limits.getLimitQueueableJobs - '+ Limits.getLimitQueueableJobs());
System.debug('Limits.getSoslQueries - '+ Limits.getSoslQueries());
System.debug('Limits.getLimitSoslQueries - '+ Limits.getLimitSoslQueries());

URL Class in Salesforce

//Create a new account called "Test Account" that we will create a link for later.
Account acc = new Account(Name = 'Test Account');
Insert acc;

//Get the base URL.
String baseURL = URL.getSalesforceBaseUrl().toExternalForm();
System.debug('Base URL: ' + baseURL);       

//Get the URL for the current request.
String currentReqURL = URL.getCurrentRequestUrl().toExternalForm();
System.debug('Current request URL: ' + currentReqURL);        

//Create the account URL from the base URL.
String accURL = URL.getSalesforceBaseUrl().toExternalForm() + '/' + acc.Id;
System.debug('URL of a particular account: ' + accURL); 

//Get some parts of the base URL.
System.debug('Host: ' + URL.getSalesforceBaseUrl().getHost());   
System.debug('Protocol: ' + URL.getSalesforceBaseUrl().getProtocol());

//Get the query string of the current request.
System.debug('Query: ' + URL.getCurrentRequestUrl().getQuery());

Generate Json Data Using Apex in Salesforce

Child Class:

public class Child{

    public String Name;
    public Child(String name) {
        this.Name = name;

Parent Class:

public class Parent{

    public Child[] ChildRecords;
    public String Name;
    public Parent(String Name) {
        this.Name = name;
        ChildRecords = new Child[0];

Pass parameters to above class using below code:

//Select Account Id from Account Object
String accountId = '0012800001A4UgG';

//Select Account & Contact Records
Account acc = [SELECT Id, Name, (SELECT Id, Name FROM Contacts) FROM Account WHERE Id =: accountId];

//Create a parent record
Parent par = new Parent(acc.Name);

//Loop on Contacts
for(Contact con: acc.Contacts) {
    par.childRecords.add(new Child(con.Name));

//Get the Json data
String jsonData = JSON.serialize(par);
System.debug('JsonData-' + jsonData);

Here is the debug log snapshot of Json data:
Json Data

Note: This is the sample class. You can modify it as per your requirement.

Salesforce HTTP Status code and Error Responses

HTTP Status Code Description
200 “OK” success code, for GET,PATCH or HEAD request.
201 “Created” success code, for POST request.
204 “No Content” success code, for DELETE request.
300 The value returned when an external ID exists in more than one record. The response body contains the list of matching records.
304 The request content has not changed since a specified date and time. The date and time is provided in a “If-Modified-Since” header.
400 The request could not be understood, usually because the ID is not valid for the particular resource. For example, if you use a userId where a groupId is required, the request returns 400.
401 The session ID or OAuth token has expired or is invalid. Or, if the request is made by a guest user, the resource isn’t accessible to guest users. The response body contains the message and errorCode.
403 The request has been refused. Verify that the context user has the appropriate permissions to access the requested data, or that the context user is not an external user.
404 Either the specified resource was not found, or the resource has been deleted.
405 The method specified in the Request-Line isn’t allowed for the resource specified in the URI.
409 A conflict has occurred. For example, an attempt was made to update a request to join a group, but that request had already been approved or rejected.
412 A precondition has failed. For example, in a batch request, if haltOnError is true and a subrequest fails, subsequent subrequests return 412.
415 The entity in the request is in a format that’s not supported by the specified method.
500 An error has occurred within Force.com, so the request could not be completed. Contact Salesforce Customer Support.
503 Too many requests in an hour or the server is down for maintenance.

Dynamic Data Creation in Salesforce From Json Data Without Using Wrapper Class

Generally for Json data insertion from external system to Salesforce, we use apex rest class and wrapper class for every object. I had a requirement to insert around 40 SF objects data from the Json data. To accomplish this requirement, I created a dynamic class, where we can insert Json data for N number of objects.

The advantage of this class is don’t need to change anything in class, If our number of object will increase or any field name will change or any field type will change. We need to change only in Custom Settings.

So, here is my article on dynamic data creation in Salesforce from json data without using wrapper class. In this article I’m going to pass Json data of Accounts & Contacts objects.

For external system data I’ve created external Id in both Account & Contact objects.

Account Object External Id Custom Field:

Contact Object External Id Custom Field:

To save SF object and Json Object information, We need to create a Custom Settings for objects.

Here is the Custom Setting Object (Json Object Mapping):
Json Object Mapping Custom Settings

Custom Setting Object (Json Object Mapping) Fields:
Json Object Mapping Fields

Custom Setting Object (Json Object Mapping) Records For Account & Contact Objects:
Json Object Mapping Records

To save SF field and Json field information, We need to create a Custom Settings for fields.
Here is the Custom Setting Object (JSon Field Mapping):
Json Field Mapping Custom Settings

Custom Setting Object (Json Field Mapping) Fields:
Json Field Mapping Fields

Custom Setting Object (Json Field Mapping) Records For Account & Contact Objects:
Json Field Mapping Records

Sample Json Data of Accounts & Contacts Objects:

"Account_List": {
	"Account": [{
		"External_Id": 833993,
		"Account_Name": "John"
		"External_Id": 833994,
		"Account_Name": "Peter"
"Contact_List": {
    "Contact": [{
		    "External_Id": 100001,
			"Last_Name": "Samal"
			"External_Id": 100002,
			"Last_Name": "Samal"

Dynamic apex rest class:

//URL Mapping
global with sharing class ApplicationProcess{

    global static ApplicationResponseMsg parseApplicationJSON() {

        //Application Response Message
        ApplicationResponseMsg appResponse = new ApplicationResponseMsg();
        //Get Custom Settings Field Mapping List
        List<Json_Field_Mapping__c> fieldMappingList = Json_Field_Mapping__c.getall().values();
        //Get Custom Settings Object Mapping List
        List<Json_Object_Mapping__c> objectMappingList = Json_Object_Mapping__c.getall().values();
        //Sequential Object Mapping List For Data insertion sequence in objects
        List<Json_Object_Mapping__c> sequentialObjectMappingList = new List<Json_Object_Mapping__c>();
        //Create Sequential List For Data insertion in objects
        for(Integer i=1; i <= objectMappingList.size(); i++){
            for(Json_Object_Mapping__c jsonObjMapping: objectMappingList){
                if(i == jsonObjMapping.Object_Insertion_Sequence__c){
        //Savepoint for transaction
        Savepoint sp = Database.setSavepoint();
        try {
            RestRequest request = RestContext.request;  
            RestResponse response = RestContext.response;
            String jSONRequestBody = request.requestBody.toString().trim();
            //Deserialize the json data
            Map<String, Object> results = (Map<String, Object>)JSON.deserializeUntyped(jSONRequestBody);
            Map<String, Object> formattedResults = new Map<String, Object>();
            if(results != null){
                formattedResults = getFormattedJsonDataMap(results);

            //Loop on Sequential Object List
            for (Json_Object_Mapping__c objMap : sequentialObjectMappingList) {
                //List For Json Data
                List<Object> JSONDataList = new List<Object>();            
                String jsonObjectListName = (objMap.Json_Object_List_Name__c).toUpperCase();
                Map<String, Object> JSONDataMap = (Map<String, Object>)formattedResults.get(jsonObjectListName);
                Map<String, Object> formattedJSONDataMap = new Map<String, Object>();
                if(JSONDataMap  != null){
                    formattedJSONDataMap = getFormattedJsonDataMap(JSONDataMap);
                if(formattedJSONDataMap != null){
                    String JSONObjectName = (objMap.Json_Object_Name__c).toUpperCase();
                    JSONDataList = (List<Object>)formattedJSONDataMap.get(JSONObjectName);

                if(JSONDataList != null){
                    if(JSONDataList.Size() > 0){
                        //Get Object wise field map list from custom setting
                        String sfObjectName = (objMap.SF_Object_Name__c).toUpperCase();
                        List<Json_Field_Mapping__c> fieldMapList = getFieldMapJsonSetting(sfObjectName, fieldMappingList);
                        //Save data
                        SaveData(JSONDataList, objMap, fieldMapList);
            appResponse.Status = 'Success';
            appResponse.Message = 'All data are saved successfully';
        catch(Exception e) {
            appResponse.Status = 'Fail';
            appResponse.Message = e.getMessage();
        return appResponse;
    //Save Data Method For Save Functionality
    private static void SaveData(List<Object> jsonDataList, Json_Object_Mapping__c objMap, List<Json_Field_Mapping__c> fieldMappingList){
        String objName = objMap.SF_Object_Name__c;
        //Make dynamic list of object
        String objListType = 'List<' + objName + '>';
        //Cast sobject list to object list
        List<SObject> sobjList = (List<SObject>)Type.forName(objListType).newInstance();
        //Main Object External ID field For Upsert
        Schema.SObjectField externalIdField;
        for (Object obj : jsonDataList)
            //Map Json Data
            Map<String, Object> jsonDataMap = (Map<String, Object>)obj;
            sObject sObj = Schema.getGlobalDescribe().get(objName).newSObject();

            for (String attributeName : jsonDataMap.keyset())
                for(Integer i=0;i<fieldMappingList.size();i++)
                    Json_Field_Mapping__c fieldMapping = fieldMappingList[i];
                    //Json Data Field Value
                    object jsonValue = jsonDataMap.get(attributeName);
                    if(fieldMapping.Json_Field_Name__c == attributeName){
                        //Save Data For Main Object
                        Boolean isExternalId = fieldMapping.Is_External_Id__c;
                        String sfFieldName = fieldMapping.SF_Field_Name__c;
                        if(!String.isempty(string.valueof(jsonValue)) && !String.isempty(sfFieldName)){
                            //Get Object Description
                            Schema.SObjectType mObjType = Schema.getGlobalDescribe().get(objName);
                            Schema.DescribeSObjectResult ObjDesc = mObjType.getDescribe();
                            //Object Data Mapping
                            sObj = ObjectDataMapping(sObj, jsonValue, objName, fieldMapping);
                            //Check external Id and add the field to external Id variable
                                externalIdField = ObjDesc.fields.getMap().get(sfFieldName);
            //Add Object List
            if(sObj != null){
        //Upsert Object Data
        if(sobjList != null){
            if(sobjList.Size() > 0){
                if(objName == 'Account'){
                    Database.Upsert((List<Account>)sobjList, externalIdField, true);
                else if(objName == 'Contact'){
                    Database.Upsert((List<Contact>) sobjList, externalIdField, true);

    //Object Data Mapping
    private static sObject ObjectDataMapping(sObject sObj, object jsonValue, String objName, Json_Field_Mapping__c fieldMapping){

		//Get Field Description
		Schema.SObjectType ObjType = Schema.getGlobalDescribe().get(objName);
		Schema.DescribeSObjectResult ObjDesc = ObjType.getDescribe();
		Schema.DescribeFieldResult fieldDesc = ObjDesc.fields.getMap().get(fieldMapping.SF_Field_Name__c).getDescribe();
        //Check Relationship (Lookup or Master Details)

            //Lookup Field Mapping
            sObject sObjLookup = Schema.getGlobalDescribe().get(fieldMapping.Relationship_Object_Name__c).newSObject();
            sObjLookup.put(fieldMapping.Relationship_SF_Field_Name__c, String.valueof(jsonValue));
            sObj.putSObject(fieldDesc.getRelationshipName(), sObjLookup);
			//Here You Can check the field type
			if(fieldDesc.getType() == Schema.DisplayType.DATETIME){
				//Do Something
            else if(fieldDesc.getType() == Schema.DisplayType.DATE){
				//Do Something
            else if(fieldDesc.getType() == Schema.DisplayType.INTEGER){
				//Do Something
        return sObj;

    //Get Field Map Json Setting
    private static List<Json_Field_Mapping__c> getFieldMapJsonSetting(string objName, List<Json_Field_Mapping__c> fieldMapJsonList){
        List<Json_Field_Mapping__c> objList = new List<Json_Field_Mapping__c>();
        for(Json_Field_Mapping__c fieldMap:fieldMapJsonList){
            if(fieldMap.SF_Object_Name__c == objName){
        return objList;
    //Get Formatted Json Data Map
    private static Map<String, Object> getFormattedJsonDataMap(Map<String, Object> results){
        Map<String, Object> formattedResult = new Map<String, Object>();
        for(String jsonObjectName: results.keySet()){
            Object jsonData = results.get(jsonObjectName);
            formattedResult.put(jsonObjectName.toUpperCase(), jsonData);
        return formattedResult;
    //Inner Class For Application Response Message
    global class ApplicationResponseMsg {
        global String Status ;
        global String message;

To test the rest class, here is the snapshot to call the apex rest class from Workbench Rest Explorer.
WorkBench Apex Rest Execute

After successfully execute the rest class with Accounts & Contacts Json data.

Created Account Records:
Account Records

Created Contact Records:
Contact Records

Note: This is the sample class. For better performance and to accomplish your requirement you can modify this class.