ABSYZ ABSYZ

  • Home

    Home

  • About us

    Who We Are

  • Our Expertise

    What we Do

  • Our Approach

    How We Do It

  • Products

    What We Made

  • Industries

    Who We Do It For

  • Clients

    Whom We Did It For.

  • Article & Blogs

    What Experts Think

  • Careers

    Join The Team

  • Get In Touch

    Let’s Get Started

ABSYZ

Data Retriever using Metadata API in Salesforce

Home / Article & Blogs / Salesforce / Integration / Metadata API / Data Retriever using Metadata API in Salesforce
By Sangamesh Gella inMetadata API, Salesforce

We often want to fetch specific data of Apex Triggers, Classes, Aura Definition Bundle and Lightning Component Bundle. We either want them to get deleted or download them as a package. We can do this by using SOQL, Tooling API and MetaData API in Apex. We implemented a functionality where we retrieve the data of Triggers, Classes, Aura Definition Bundle and Lightning Component Bundle, a certain profile has been written over a period of time and make it as package.xml format which then is sent to another class where it gets deleted. How did we do it? What are the challenges we faced? How did we overcome those challenges?

❝Let’s take a look at it step by step. But before understanding the actual process let’s unlearn what Tooling API and MetaData API in Salesforce are:❞

Tooling API

The Tooling API in Salesforce is a REST-based API that provides programmatic access to custom metadata types, Apex classes, and other tools for customizing and extending the Salesforce platform. It is typically used by integrated development environments (IDEs) and other tools for automating the development and deployment of custom code and metadata in Salesforce. The Tooling API enables developers to perform operations such as creating, updating, and deleting Apex classes, triggers, Visualforce pages, and custom metadata types, as well as retrieving information about the metadata and data in a Salesforce organization.

MetaData API

The Metadata API in Salesforce is a SOAP-based API that provides programmatic access to the metadata of Salesforce, including the customization of standard objects, fields, and other components. It is typically used by development tools and integrations to automate the process of deploying and managing customizations across multiple Salesforce orgs.

With the Metadata API, developers can perform operations such as creating, updating, and deleting custom objects, fields, and other components, retrieving metadata information, and deploying metadata changes between different Salesforce organizations. The Metadata API also provides access to more advanced features, such as the creation of custom tabs, page layouts, and workflows.

The first class we are going to understand is DataRetrieverUsingToolingAPI.apxc. This is constructed to retrieve the data of Apex Triggers, Classes, Aura Definition Bundle, Lightning Component Bundle written by particular profile. We have to break this class down into two parts. Why? Because Apex Triggers, Classes and Aura Definition Bundle are something which can be fetched by writing SOQL query in the SOQL query editor. But Lightning Component Bundle cannot be fetched like that, we have to enable the Tooling API option which does return the data we intend to have.

The first part is writing methods to fetch Apex Triggers, Classes, Aura Definition Bundle and second part is to fetch Lightning Component Bundle. Let’s take a look at the process of retrieving the Apex Triggers which will be applicable for fetching the Classes and Aura Definition Bundle as well.

Here you can see we declared a variable which is null and then wrote a query to fetch all the triggers written by the CandidateUser (specific to our internal use case, it varies). And we are checking the size of the list and then updating the variable with a string ‘<types>’ and then looping over the list to form members which you can see as we are appending to the string we defined at the beginning. Now that we have the members we need to make the code understand that this is of type Apex Trigger. Hence, outside the for loop we are appending the Apex Trigger part for the other class to understand that is Apex Trigger. The same is applicable for the Apex Classes and Aura Definition bundle where there will be a change in the defining.

public static String FetchApexTriggers() {
        String apexrTriggerString = '';
        List<ApexTrigger> apexTriggerList = [SELECT Id, Name FROM ApexTrigger WHERE CreatedBy.Name = 'CandidateUser'];
        if(apexTriggerList.size() > 0) {
            apexrTriggerString = '<types>';
            for(ApexTrigger apexTriggerVar: apexTriggerList) {
                apexrTriggerString+='<members>'+apexTriggerVar.Name+'</members>';
            }
            apexrTriggerString+='<name>ApexTrigger</name></types>';
            return apexrTriggerString;
        } else {
            return apexrTriggerString;
        }
    }

Here you can see we declared a variable which is null and then wrote a query to fetch all the triggers written by the CandidateUser (specific to our internal use case, it varies). And we are checking the size of the list and then updating the variable with a string ‘<types>’ and then looping over the list to form members which you can see as we are appending to the string we defined at the beginning. Now that we have the members we need to make the code understand that this is of type Apex Trigger. Hence, outside the for loop we are appending the Apex Trigger part for the other class to understand that is Apex Trigger. The same is applicable for the Apex Classes and Aura Definition bundle where there will be a change in the defining.

The second part which will be very interesting and it personally left me intrigued while developing this because I proceeded by writing the same part for the Lightning Component bundle as well, but later realized that there is something that we are missing here and after understanding what the error is we overcame the challenge. Here how we fetched the Apex Triggers, Classes, and Aura Definition Bundle it won’t be possible to fetch the Lightning Component Bundle. For that reason, we have to use the Tooling API and how can we do this? The following part has been broken down into four methods:

1) FetchLightningComponentBundle(List<Object> responseList)

Method which forms the xml format when the response is received from the restGet method

2) RestGet(String endPoint, String method, String sid)

Method which helps in hitting the end point and retrieving the Lightning Component Bundle details

3) ToolingAPISOQL(String query)

Method to call restGet method which takes three parameters which are as follows: endpoint, HTTP request method and session id

4) FetchLightningComponentBundleQuery()

Method to call toolingAPISOQL by passing the query as string.

/**
* @description : to form a string with the type of lightning component bundle and it's respective members written by the candidate user
* @author Sangamesh Gella - ABSYZ Software Consulting Private Limited | 01-27-2023 
* @param List<Object> responseList 
* @return String 
**/
public static String FetchLightningComponentBundle(List<Object> responseList) {

    String lightningComponentBundleString = '';

    if(responseList.size() > 0) {
        lightningComponentBundleString = '<types>';
        for(Object lightningComponentBundleVar: responseList) {
            Map<String, Object> componentsMap = (Map<String, Object>) JSON.deserializeUntyped(JSON.serialize(lightningComponentBundleVar));
            lightningComponentBundleString+='<members>'+componentsMap.get('DeveloperName')+'</members>';
        }
        lightningComponentBundleString+='<name>LightningComponentBundle</name></types>';
        return lightningComponentBundleString;
    } else {
        return lightningComponentBundleString;
    }
}

/**
* @description : to fetch the lightning web components written by the candidate using tooling API structure
* @author Sangamesh Gella - ABSYZ Software Consulting Private Limited | 01-27-2023 
* @param String endPoint 
* @param String method 
* @param String sid 
* @return String 
**/
public static String restGet(String endPoint, String method, String sid) {

    List<String> lwcNames = new List<String>();

    Map<String, Object> responseMap =  new Map<String, Object>();

    List<Object> responseList = new List<Object>();

    try {
        Http httpVar = new Http();
        HttpRequest httpReqVar = new HttpRequest();
        httpReqVar.setHeader('Authorization', 'Bearer ' + sid);
        httpReqVar.setTimeout(60000);
        httpReqVar.setEndpoint(endpoint);
        httpReqVar.setMethod(method);
        HttpResponse responseVar = httpVar.send(httpReqVar);
        System.debug(responseVar);
        if(responseVar.getStatusCode() == 200) {
            responseMap = (Map<String, Object>) JSON.deserializeUntyped(responseVar.getBody());
            responseList = (List<Object>) responseMap.get('records');
            System.debug('Response List is: ' + responseList);
            if(responseList.size() > 0) {
               FetchLightningComponentBundle(responseList);
            }
            return '';
        }
        return '';
    } catch (Exception ex) {
        System.debug('Exception in tooling API Call: ' + ex.getMessage());
        return ex.getMessage();
    }
}


/**
* @description : method to form query in the form we write for the workbench as a Tooling API
* @author Sangamesh Gella - ABSYZ Software Consulting Private Limited | 01-27-2023 
* @param String query 
* @return String 
**/
public static String toolingAPISOQL(String query) {
    String baseURL = 'https://absyz213-dev-ed.develop.my.salesforce.com//services/data/v56.0/tooling/query?';
    System.debug('Query is: ' + restGet(baseURL +'q='+ (query.replace(' ' , '+')),'GET', UserInfo.getSessionId().subString(15)));
    return restGet( baseURL +'q='+ (query.replace(' ' , '+')), 'GET', UserInfo.getSessionId().subString(15));
}

/**
* @description : method for query as a string to fetch the lightning web components written by the candidate
* @author Sangamesh Gella - ABSYZ Software Consulting Private Limited | 01-27-2023 
* @return String 
**/
public static String FetchLightningComponentBundleQuery() {
    String soql = 'SELECT Id,DeveloperName FROM LightningComponentBundle WHERE CreatedBy.Name = \'CandidateUser\'';
    String body = toolingAPISOQL(soql);
    System.debug('Body is: ' + body);
    return body;
}
}

We can retrieve the apex triggers, classes, aura definition bundle, lightning component bundle, vf pages using SOQL and Metadata API in Salesforce. We can further download or delete the data on a basis. For further details, you can contact Gella Sangamesh Gupta at sangamesh.gella@absyz.com or Vijay Sai Mahajan at vijaysai.mahajan@absyz.com

get in touch
Data Retriever using Metadata APIMetadata API
26
Like this post
5 Posts
Sangamesh Gella

Search Posts

Archives

Categories

Recent posts

All About The OmniStudio FlexCards

All About The OmniStudio FlexCards

Boost Customer Experience With Repeater Widget in CRM Analytics

Boost Customer Experience With Repeater Widget in CRM Analytics

Enhance Insights Using Custom Tooltips In CRM Analytics

Enhance Insights Using Custom Tooltips In CRM Analytics

Net zero as a Service In CPG Industry

Net zero as a Service In CPG Industry

How Do We Import an External Library into Salesforce Lightning?

How Do We Import an External Library into Salesforce Lightning?

  • Tableau CRM: Compute Relative Functionality In Recipe
    Previous PostTableau CRM: Compute Relative Functionality In Recipe
  • Next PostFile Upload In GraphQL With Apollo Server Using S3 Bucket & Node.js
    Tableau CRM: Compute Relative Functionality In Recipe

Related Posts

All About The OmniStudio FlexCards
OmniStudio Salesforce

All About The OmniStudio FlexCards

Boost Customer Experience With Repeater Widget in CRM Analytics
CRM Analytics Salesforce

Boost Customer Experience With Repeater Widget in CRM Analytics

Enhance Insights Using Custom Tooltips In CRM Analytics
CRM Analytics Salesforce

Enhance Insights Using Custom Tooltips In CRM Analytics

How Do We Import an External Library into Salesforce Lightning?
Lightning Salesforce

How Do We Import an External Library into Salesforce Lightning?

Leave a Reply (Cancel reply)

Your email address will not be published. Required fields are marked *

*
*

ABSYZ Logo

INDIA | USA | UAE

  • About us
  • Article & Blogs
  • Careers
  • Get In Touch
  • Our Expertise
  • Our Approach
  • Products
  • Industries
  • Clients
  • White Papers

Copyright ©2022 Absyz Inc. All Rights Reserved.

youngsoft
Copy
We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “ACCEPT ALL”, you consent to the use of ALL the cookies. However, you may visit "Cookie Settings" to provide a controlled consent. Privacy Policy
Cookie SettingsREJECT ALLACCEPT ALL
Manage consent

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary
Always Enabled

Necessary cookies are absolutely essential for the website to function properly. These cookies ensure basic functionalities and security features of the website, anonymously.

CookieDurationDescription
cookielawinfo-checkbox-analytics11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Analytics".
cookielawinfo-checkbox-functional11 monthsThe cookie is set by GDPR cookie consent to record the user consent for the cookies in the category "Functional".
cookielawinfo-checkbox-necessary11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookies is used to store the user consent for the cookies in the category "Necessary".
cookielawinfo-checkbox-others11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Other.
cookielawinfo-checkbox-performance11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Performance".
viewed_cookie_policy11 monthsThe cookie is set by the GDPR Cookie Consent plugin and is used to store whether or not user has consented to the use of cookies. It does not store any personal data.

Functional

Functional cookies help to perform certain functionalities like sharing the content of the website on social media platforms, collect feedbacks, and other third-party features.

Performance

Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.

Analytics

Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics the number of visitors, bounce rate, traffic source, etc.

Advertisement

Advertisement cookies are used to provide visitors with relevant ads and marketing campaigns. These cookies track visitors across websites and collect information to provide customized ads.

Others

Other uncategorized cookies are those that are being analyzed and have not been classified into a category as yet.

SAVE & ACCEPT