top of page
  • Writer's pictureS. Chaudhary

CREATING A CUSTOM OBJECT IN SALESFORCE USING APEX

Updated: Nov 8, 2023



In Salesforce, users can create custom objects via two main routes. The primary and more straightforward method is utilizing the Object Manager's user interface, where you click the "New" button and define the object as needed. Alternatively, for a more dynamic approach, users can leverage the power of code to achieve this task. In this context, the MetadataService class becomes our tool of choice.


Salesforce's Metadata API provides developers with a versatile means of interfacing with the platform's metadata. By leveraging this API, one can manage and customize various aspects of their Salesforce instance. In today's guide, we'll specifically focus on how you can utilize the `MetadataService` class to create custom objects.


1. Preparing the MetadataService:

Before delving into the code:

  1. Ensure the MetadataService class is present in your Salesforce org.

  2. This class is available on the FinancialForce GitHub repository.

  3. Once acquired, deploy the class to your Salesforce org using tools such as the Salesforce CLI or Workbench.

2. Grasping the MetadataService:

MetadataService acts as a wrapper for Salesforce's Metadata API. This allows for operations like creation, retrieval, modification, and deletion of metadata items including but not limited to Custom Objects, Layouts, and Custom Fields, directly from Apex.


3. Introducing the MetadataServiceHandler Class:

To facilitate the creation of custom objects, we'll use a helper class, MetadataServiceHandler, which will in turn utilize the standard methods from MetadataService class.

public with sharing classMetaDataServiceHandler {
    publicstatic void createObject(String   objectName, String objectAPI, String   objectPlural) {
        MetadataService.MetadataPort   metadataservice = new MetadataService.MetadataPort();
        metadataservice.SessionHeader =   new MetadataService.SessionHeader_element();
         metadataservice.SessionHeader.sessionId =UserInfo.getSessionId();
         List<MetadataService.CustomObject> objectList = newList<MetadataService.CustomObject>();
        MetadataService.CustomObject   customobject = new MetadataService.CustomObject();
        customobject.fullName =   objectAPI;
        customobject.label =   objectName;
        customobject.pluralLabel =   objectPlural;
        customObject.nameField = newMetadataService.CustomField();
        customobject.nameField.type_x =   'Text';
        customobject.nameField.label = 'Name';
        customobject.deploymentStatus =   'Deployed';
        customObject.sharingModel = 'ReadWrite';
        objectList.add(customobject);
         metadataservice.createMetadata(objectList);
    }
   }

Here's a concise explanation of the key components:

fullName: Represents the API name of your object. Custom objects should always end with ‘__c’.

label & pluralLabel: These dictate how the object will be displayed within Salesforce's UI.

deploymentStatus: When set to 'Deployed', the object becomes readily available. If not, it stays in a developmental phase.

sharingModel: This is an indicator of the data access settings. A 'ReadWrite' status allows users to both view and modify the data by default.


Once the class is in place, you can effortlessly create your custom object within Salesforce by invoking the provided method.


MetaDataServiceHandlerMock.cls

@isTest
 public classMetaDataServiceHandlerMockimplementsWebServiceMock {
public void doInvoke(
Object stub, Object request, Map<String, Object> response,
String endpoint, String soapAction, String requestName,
String responseNS, String responseName, String responseType
){
if(request instanceof MetadataService.retrieve_element)
response.put('response_x', new MetadataService.retrieveResponse_element());
elseif(request instanceof MetadataService.checkDeployStatus_element)
response.put('response_x', new MetadataService.checkDeployStatusResponse_element());
elseif(request instanceof MetadataService.listMetadata_element)
response.put('response_x', new MetadataService.listMetadataResponse_element());
elseif(request instanceof MetadataService.checkRetrieveStatus_element)
response.put('response_x', new MetadataService.checkRetrieveStatusResponse_element());
elseif(request instanceof MetadataService.describeMetadata_element)
response.put('response_x', new MetadataService.describeMetadataResponse_element());
elseif(request instanceof MetadataService.deploy_element)
response.put('response_x', new MetadataService.deployResponse_element());
elseif(request instanceof MetadataService.updateMetadata_element)
response.put('response_x', new MetadataService.updateMetadataResponse_element());
elseif(request instanceof MetadataService.renameMetadata_element)
response.put('response_x', new MetadataService.renameMetadataResponse_element());
elseif(request instanceofMetadataService.cancelDeploy_element)
response.put('response_x', new MetadataService.cancelDeployResponse_element());
elseif(request instanceofMetadataService.deleteMetadata_element)
response.put('response_x', new MetadataService.deleteMetadataResponse_element());
elseif(request instanceofMetadataService.upsertMetadata_element)
response.put('response_x', new MetadataService.upsertMetadataResponse_element());
elseif(request instanceofMetadataService.createMetadata_element)
response.put('response_x', new MetadataService.createMetadataResponse_element());
elseif(request instanceofMetadataService.deployRecentValidation_element)
response.put('response_x', new MetadataService.deployRecentValidationResponse_element());
elseif(request instanceof MetadataService.describeValueType_element)
response.put('response_x', new MetadataService.describeValueTypeResponse_element());
elseif(request instanceof MetadataService.checkRetrieveStatus_element)
response.put('response_x', new MetadataService.checkRetrieveStatusResponse_element());
return;
}
 }

MetaDataServiceHandlerTest.cls

@isTest
   public with sharing class MetaDataServiceHandlerTest {
    @isTest
    static void positiveTest() {
         test.setMock(WebServiceMock.class, new MetaDataServiceHandlerMock());
        test.startTest();
            MetaDataServiceHandler.createObject('test',   'test__c', 'tests');
        test.stopTest();
    }
   }

Remember, with the flexibility and power of Apex, you can extend this approach to suit a variety of metadata-related operations, allowing for a highly tailored Salesforce environment.


Happy Coding! You can leave a comment to help me understand how the blog helped you. If you need further assistance, please contact us. You can click "Reach Us" on the website and share the issue with me.



Blog Credit:

S. Chaudhary

Salesforce Developer

Avenoir Technologies Pvt. Ltd.

Reach us: team@avenoir.ai

Recent Posts

See All
bottom of page