About Me

My photo
PLANO, Texas, United States

Tuesday, October 27, 2020

Apex Metadata API

Before going to explain Apex Metadata API, I would like to explain the pain area. I was working on one of my projects as a development lead. We used to have daily deployment. For most of the deployment requests, we need to add the field in a layout. We don't want to move the entire page layout so we always use to do manual stuff. Apex Metadata API helps here.
  • The Apex Metadata API lets you make metadata changes directly from Apex. You can automate configuration changes and many steps like post-install can be done easily without any manual intervention. 

  • Metadata access in Apex is available for Apex classes using API version 40.0 and later. Metadata.Operations class is used for the metadata operation.


What are the methods in Metadata.Operations class?

Retrieve and deploy metadata using the Metadata.Operations class.


  • clone() - Makes a duplicate copy of the Metadata.Operations.

  • enqueueDeployment(container, callback)
    Deploys custom metadata components asynchronously.

  • retrieve(type, fullNames)
    Retrieves a list of custom metadata components.


Retrieve Metadata

Use the Metadata.Operations.retrieve() method to synchronously retrieve metadata from the current org. Provide a list of metadata component names that you want to retrieve. Salesforce returns a list of matching component data, represented by component classes that derive from Metadata.Metadata

Syntax-

retrieve(type, fullNames)

Parameters

  1. Type-  Metadata.MetadataType

The metadata component type.

  1. fullNames- List<String>

A list of component names to retrieve. For information on component name formats, see Metadata.fullName().

Return Value

Type: List<Metadata.Metadata>

 

Example-

public class UpdateContactPageLayout {

   // Add custom field to page layout

   public Metadata.Layout addLayoutItem() {

       // Retrieve Contact layout and section

       List<Metadata.Metadata> layoutsListMetadata.Operations.retrieve(Metadata.MetadataType.Layout,

           new List<String> {'Contact-Contact Layout'});

       Metadata.Layout layoutMetadata = (Metadata.Layout) layoutsList.get(0);

       Metadata.LayoutSection contactLayoutSection = null;

       //List<Metadata.LayoutSection> contactLayoutSections = layoutMetadata.layoutSections;

       for (Metadata.LayoutSection section : layoutMetadata.layoutSections) {

           if (section.label == 'Additional Information') {

               contactLayoutSection = section;

               break;

           }

       }

      

       // Add the field under Additional Information section in the left column

       List<Metadata.LayoutColumn> contactColumns = contactLayoutSection.layoutColumns;    

       List<Metadata.LayoutItem> contactLayoutItems = contactColumns.get(0).layoutItems;

      

       // Create a new layout item for the custom field

       Metadata.LayoutItem newField  = new Metadata.LayoutItem();

       newField.behavior = Metadata.UiBehavior.Edit;

       newField.field = 'AMAPI__Apex_MD_API_Twitter_name__c';

       contactLayoutItems.add(newField);

      

       return layoutMetadata;

   }

}

 

 

Deploy Metadata

Use the Metadata.Operations.enqueueDeployment() method to asynchronously deploy metadata to the current org. Deployment is queued for asynchronous processing. When deploying metadata, you can create and update components, but not delete components. 

Syntax

enqueueDeployment(container, callback)

Parameters

  1. container: Metadata.DeployContainer (Container that contains the set of metadata components to deploy.)

  2. callback: Metadata.DeployCallback (A class that implements the Metadata.DeployCallback interface. Used by Salesforce to return information about the deployment results.)

Return Value

Type: Id (ID of deployment request.)


Example


public class CreateMetadata{

   public void updateAndDeployMetadata() {

     // Setup custom metadata to be created in the subscriber org.

     Metadata.CustomMetadata customMetadatanew Metadata.CustomMetadata();

     customMetadata.fullName = 'ISVNamespace__MetadataTypeName.MetadataRecordName';

 

     Metadata.CustomMetadataValue customField = new Metadata.CustomMetadataValue();

     customField.field = 'customField__c';

     customField.value = 'New value';

 

     customMetadata.values.add(customField);

 

     Metadata.DeployContainer mdContainer = new Metadata.DeployContainer();

     mdContainer.addMetadata(customMetadata);

 

     // Setup deploy callback, MyDeployCallback implements

     // the Metadata.DeployCallback interface (code for

     // this class not shown in this example)

     MyDeployCallback callback = new MyDeployCallback();

 

     // Enqueue custom metadata deployment

     Id jobId = Metadata.Operations.enqueueDeployment(mdContainer, callback);

   }

 }




Testing Metadata Deployments

// DeployCallbackContext subclass for testing that returns myJobId

public class TestingDeployCallbackContext extends Metadata.DeployCallbackContext {

   private myJobId = null; // define to a canned ID you can use for testing

   public override Id getCallbackJobId() {

     return myJobId;

   }

 }


Limitation


Metadata access in Apex is limited to types and components that support the use cases described in Metadata. Apps and packages can use the metadata feature in Apex to retrieve and deploy the following metadata types and components:

  • Records of custom metadata types

  • Layouts


Security Considerations

Three features of Apex Metadata API safeguard your orgs and data.

Restrictions on the types of metadata that can be created or modified.

  • To ensure security, Salesforce restricts the types of metadata that can be created or modified with Apex Metadata API. The initial release of Apex Metadata API allows you to work with two metadata types: page layouts and records of custom metadata types. This careful approach to supporting metadata ensures that installed packages can work only with safe metadata types, which can be modified in predictable ways.

  • Salesforce also doesn’t allow creating Apex classes, Visualforce pages, or Lightning components via Apex. As you can imagine, if managed packages could write code in a subscriber org, it would be difficult for Salesforce to enforce security for the package. In addition, to ensure that installed apps only modify metadata types in predictable ways, Salesforce doesn’t support automated code generation.

Restrictions on the apps that can deploy changes.

In addition to restricting the types of metadata that can be created or modified, Salesforce limits which packages can deploy metadata via Apex. Apex Metadata API can execute deployments in only three scenarios:

  • From certified managed packages that are provided by known, registered ISVs.

  • From uncertified managed packages, but only if the subscriber org enables a specific Apex setting, which we discuss shortly.

  • From unmanaged packages, which means that the code is owned by the org that executes it.

Detailed audit histories that track metadata changes.

  • You can verify the behavior of managed packages in the Setup audit trail log. 

  • All metadata operations that use the Apex Metadata API are tracked in the log. The namespace of the code performing the deployment is recorded, which means that you always know which namespace made changes, and when the changes were made. The Setup audit trail log is located under Setup | View Setup Audit Trail.


Reference  


1 comment:

  1. Anyone looking for Salesforce app which save their time and can perform bulk CRUD operations in few click - their search end at Salesforce Appexchange app Bulk Object Field Creator
    Most recommended and appreciable app by Salesforce MVP

    ReplyDelete