RehberSalesforce

Salesforce Metadata API: Geliştiriciler İçin Kapsamlı Rehber

Salesforce platformu üzerinde geliştirme yapıyorsanız, konfigürasyon değişikliklerini yönetmek ve dağıtmak günlük işlerinizin önemli bir parçasıdır. Bu süreçleri manuel olarak gerçekleştirmek, özellikle karmaşık projelerde, ciddi zaman kaybı yaratabilir. İşte tam bu noktada Salesforce Metadata API devreye giriyor. Bu güçlü API, Salesforce konfigürasyonlarınızı programatik olarak yönetmenize olanak tanıyarak geliştirme süreçlerinizi otomatikleştirmenize ve hızlandırmanıza imkan sağlar.

Bu yazımızda, Salesforce Metadata API’nin temellerinden ileri düzey kullanımına kadar kapsamlı bir rehber sunuyoruz. Hem yeni başlayan geliştiricilerin hem de deneyimli Salesforce uzmanlarının faydalanabileceği pratik bilgiler ve kod örnekleri ile bu güçlü aracı projelerinizde nasıl etkili şekilde kullanabileceğinizi öğreneceksiniz.

Metadata API Nedir?

Salesforce Metadata API, platform üzerindeki meta verileri (metadata) programatik olarak oluşturmanıza, güncelemenize ve yönetmenize olanak tanıyan güçlü bir web servisidir. Meta veri, Salesforce organizasyonunuzdaki yapılandırma bilgilerini temsil eder – özel nesneler, alanlar, sayfa düzenleri, Apex sınıfları, Lightning bileşenleri ve daha fazlası.

Bu API, SOAP (Simple Object Access Protocol) tabanlıdır ve XML mesajları aracılığıyla iletişim kurar. Salesforce’un diğer API’leri genellikle veri manipülasyonuna odaklanırken (örn. REST API ve SOAP API), Metadata API özellikle konfigürasyon bileşenlerinin yönetimi için tasarlanmıştır.

Metadata API, Salesforce platformundaki diğer geliştirme araçlarının temelini oluşturur. Örneğin, Salesforce CLI, Visual Studio Code için Salesforce Uzantısı ve Change Set’ler gibi araçlar arka planda Metadata API’yi kullanır.

Metadata API’nin Kullanım Alanları

Metadata API’nin sağladığı programatik erişim, birçok güçlü kullanım senaryosunu mümkün kılar:

Konfigürasyon Yönetimi

  • Organizasyonlar arasında (sandbox’tan üretime veya bir müşteri ortamından diğerine) konfigürasyon değişikliklerini aktarma
  • Mevcut organizasyon yapılandırmalarının yedeklerini alıp saklama
  • Organizasyon konfigürasyonlarını kod olarak (Configuration as Code) yönetme

Deployment Otomasyonu

  • Sürekli Entegrasyon/Sürekli Dağıtım (CI/CD) pipeline’larında otomatik build ve deployment işlemleri
  • Planlı release’ler için otomatikleştirilmiş deployment süreçleri oluşturma
  • Çoklu ortamlara paralel deploymentlar gerçekleştirme

DevOps Entegrasyonu

  • Git gibi versiyon kontrol sistemleriyle entegrasyon
  • Jenkins, GitHub Actions veya Azure DevOps gibi CI/CD araçlarıyla entegre çalışma
  • Deployment süreçlerini izleme ve raporlama

Metadata API ile Çalışmaya Başlama

Metadata API ile çalışmaya başlamadan önce, aşağıdaki gereksinimleri sağladığınızdan emin olmalısınız:

  1. API Erişimi Olan Salesforce Hesabı: Organizasyonunuzda API erişiminizin etkinleştirilmiş olması gerekir.
  2. Kimlik Doğrulama Bilgileri: Kullanıcı adı, şifre ve güvenlik token’ı veya OAuth 2.0 kimlik doğrulaması.
  3. WSDL Dosyası: Metadata API’ye erişmek için Enterprise WSDL veya Partner WSDL dosyasına ihtiyacınız var.

Bağlantı Kurma

Metadata API’ye bağlanmak için öncelikle bir kimlik doğrulama yöntemi seçmelisiniz. En yaygın yöntemler şunlardır:

Kullanıcı Adı-Şifre Kimlik Doğrulaması:

// Java örneği
ConnectorConfig config = new ConnectorConfig();
config.setUsername(“[email protected]“);
config.setPassword(“sifre+guvenlikToken“);
config.setAuthEndpoint(“https://login.salesforce.com/services/Soap/c/55.0“);
MetadataConnection metadataConnection = com.sforce.soap.metadata.Connector.newConnection(config);

OAuth 2.0 Kimlik Doğrulaması:


// Node.js örneği (JSForce kullanarak)
const jsforce = require(‘jsforce‘);
const conn = new jsforce.Connection({
   oauth2: {
      clientId: ‘CONNECTED_APP_CLIENT_ID’,
      clientSecret: ‘CONNECTED_APP_CLIENT_SECRET’,
      redirectUri: ‘CALLBACK_URL’
   }
});

conn.login([email protected], ‘sifre+guvenlikToken’, (err, userInfo) => {
    if (err) { return console.error(err); }

  // Metadata API’ye erişim
   conn.metadata.list([{type: ‘CustomObject’}], function(err, results) {
      if (err) { return console.error(err); }
      console.log(‘metadata list: ‘, results);
   });
});

API Sürümü Seçimi

Metadata API’nin hangi sürümünü kullanacağınızı belirtmek önemlidir. Genellikle, organizasyonunuzun desteklediği en son sürümü kullanmanız önerilir, ancak bazı durumlarda belirli bir sürümü kullanmanız gerekebilir.

<!– SOAP isteği örneği –>
<soapenv:Envelope xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/”
      xmlns:met=”http://soap.sforce.com/2006/04/metadata”>
     <soapenv:Header>
          <met:SessionHeader>
                 <met:sessionId>SESSION_ID</met:sessionId>
          </met:SessionHeader>
     </soapenv:Header>
     <!– API çağrıları burada –>
  </soapenv:Envelope>

Temel Metadata Operasyonları

Metadata API ile gerçekleştirebileceğiniz temel işlemler şunlardır:

1. Metadata Bileşenlerini Okuma (Retrieve)

Mevcut bir organizasyondaki belirli metadata bileşenlerini almak için retrieve işlemi kullanılır:

// Java örneği
RetrieveRequest retrieveRequest = new RetrieveRequest();
retrieveRequest.setApiVersion(55.0);

// Belirli bir paket içeriğini alma
retrieveRequest.setPackageNames(new String[] { “MyPackage” });
// Veya belirli metadata türlerini alma
retrieveRequest.setSpecificFiles(new String[] { “objects/Account.object” });

AsyncResult asyncResult = metadataConnection.retrieve(retrieveRequest);
RetrieveResult result = metadataConnection.checkRetrieveStatus(asyncResult.getId());

// Sonuçları işleme
if (result.getStatus() == RetrieveStatus.Succeeded) {
        // Metadata zip dosyasını kullanma
        byte[] zipBytes = result.getZipFile();
        // Zip’ten dosyaları çıkarma ve işleme…
}

2. Metadata Bileşenlerini Yazma (Deploy)

Organizasyona yeni metadata bileşenleri eklemek veya mevcut olanları güncellemek için deploy işlemi kullanılır:

// Node.js örneği (JSForce kullanarak)
// Metadata dosyaları zip dosyasında paketlenir
const zipBuffer = fs.readFileSync(‘metadata.zip’);

conn.metadata.deploy(zipBuffer, { rollbackOnError: true })
    .on(‘progress’, (result) => {
     console.log(`Deploy ID: ${result.id}`);
     console.log(`Status: ${result.status}`);
     console.log(`Tamamlanan: ${result.numberComponentsDeployed}/${result.numberComponentsTotal}`);
})
.complete((err, result) => {
    if (err) { return console.error(err); }
    console.log(`Deployment ${result.status}`);
    if (result.status === ‘Failed’) {
       // Hata detaylarını işleme
      console.error(result.details.componentFailures);
  }
});

3. Metadata Bileşenlerini Silme

Organizasyondan metadata bileşenlerini kaldırmak için:

// Java örneği
DeleteMetadata deleteMetadata = new DeleteMetadata();
deleteMetadata.setType(“CustomObject”);
deleteMetadata.setFullNames(new String[] { “CustomObject__c” });

AsyncResult[] results = metadataConnection.deleteMetadata(deleteMetadata);
for (AsyncResult result : results) {
       if (result.isSuccess()) {
            System.out.println(“Bileşen başarıyla silindi.”);
        } else {
             System.out.println(“Hata: “ + result.getStatusCode() + ” – “ + result.getMessage());
     }
}

İleri Seviye Kullanım

Batch İşlemleri

Metadata API’nin çağrı limitleri bulunmaktadır. Bu limitleri aşmamak ve büyük miktarda metadata ile çalışmak için batch işlemleri kullanabilirsiniz:

// Node.js örneği – Batch işlemi
const metadataTypes = [
   { type: ‘CustomObject‘, folder: null },
   { type: ‘Layout’, folder: null },
   { type: ‘ApexClass’, folder: null }
]

// Her tür için ayrı ayrı list çağrısı yapma
Promise.all(metadataTypes.map(type => {
     return new Promise((resolve, reject) => {
       conn.metadata.list([type], (err, results) => {
          if (err) { return reject(err); }
          resolve(results);
      });
  });
}))
.then(results => {

// Tüm sonuçları birleştirme
  const allMetadata = [].concat(results);
  console.log(`Toplam ${allMetadata.length} metadata bileşeni bulundu.`);
})
.catch(err => {
   console.error(‘Hata:’, err);
});

Async Operasyonlar

Büyük metadata işlemleri zaman alabilir. Asenkron işlemlerle, uzun süren işlemleri başlatabilir ve daha sonra durumlarını kontrol edebilirsiniz:

// Java örneği – Asenkron deployment
DeployOptions deployOptions = new DeployOptions();
deployOptions.setPerformRetrieve(false);
deployOptions.setRollbackOnError(true);
deployOptions.setTestLevel(TestLevel.RunLocalTests);

AsyncResult asyncResult = metadataConnection.deploy(zipBytes, deployOptions);
String deployId = asyncResult.getId();

// Deployment durumunu kontrol etme

boolean isDone = false;
DeployResult deployResult = null;

while (!isDone) {
    Thread.sleep(5000); // 5 saniye bekle
    deployResult = metadataConnection.checkDeployStatus(deployId, true);
    isDone = deployResult.isDone();

    System.out.println(“Deploy durumu: “ + deployResult.getStatus() +
                                   “, Tamamlanan: “ + deployResult.getNumberComponentsDeployed() +
“/” + deployResult.getNumberComponentsTotal());
}

if (deployResult.getStatus() == DeployStatus.Succeeded) {
     System.out.println(“Deployment başarılı!”);
} else {
      // Hataları işleme
     DeployMessage[] msgs = deployResult.getMessages();
     for (DeployMessage msg : msgs) {
            if (msg.getProblem() != null) {
                 System.out.println(“Hata: “ + msg.getFileName() + ” – “ + msg.getProblem());
         }
   }
}

Büyük Ölçekli Deploymentlar İçin Stratejiler

Büyük organizasyonlarda çalışırken, deployment stratejinizi optimize etmek önemlidir:

  1. Seçici Deployment: Sadece değişen bileşenleri deploy edin, tüm paketi değil.
  2. Paralel İşlemler: Bağımsız bileşenleri paralel olarak deploy edin.
  3. Test Stratejisi: Deployment sırasında çalıştırılacak testleri akıllıca seçin (TestLevel kullanımı).
  4. Validasyon: Gerçek deployment öncesinde validateOnly=true ile doğrulama yapın.

// Node.js örneği – Validasyon sonra deployment
// Önce validasyon
conn.metadata.deploy(zipBuffer, {
    validateOnly: true,
    testLevel: ‘RunLocalTests’ 
})

.complete((err, result) => {
    if (err) { return console.error(err); }

    if (result.success) {
      console.log(‘Validasyon başarılı, gerçek deployment başlatılıyor…’);

    // Validasyon başarılıysa, gerçek deployment
    conn.metadata.deploy(zipBuffer, {
        rollbackOnError: true,
        testLevel: ‘RunLocalTests’
   })
   .complete((err, finalResult) => {
      if (err) { return console.error(err); }
      console.log(`Deployment ${finalResult.status}`);
   });
 } else {
     console.error(‘Validasyon başarısız:’, result.details.componentFailures);
     }
});

En İyi Uygulama Örnekleri

Performans Optimizasyonu

  • Küçük Paketler: Büyük tek bir deployment yerine, küçük mantıksal paketlerle çalışın.
  • Öncelik Sırası: Bağımlılıklara sahip bileşenleri doğru sırada deploy edin.
  • Paketleme Stratejisi: İlişkili bileşenleri birlikte paketleyin (örn. özel nesneler ve ilgili alanları).

Güvenlik En İyi Uygulamaları

  • Kimlik Bilgileri Yönetimi: API anahtarları ve kimlik bilgilerini asla kod içinde saklamamalısınız.
  • En Az Ayrıcalık İlkesi: Deployment kullanıcılarına sadece gerekli minimum izinleri verin.
  • IP Kısıtlamaları: Mümkünse, API erişimlerini belirli IP adresleriyle sınırlandırın.

// Node.js örneği – Güvenli bağlantı yönetimi
require(‘dotenv’).config(); // .env dosyasından çevre değişkenlerini yükleme

const conn = new jsforce.Connection({
    oauth2: {
         clientId: process.env.SF_CLIENT_ID,
         clientSecret: process.env.SF_CLIENT_SECRET,
         redirectUri: process.env.SF_REDIRECT_URI
     },
     instanceUrl: process.env.SF_INSTANCE_URL,
     accessToken: process.env.SF_ACCESS_TOKEN,
     refreshToken: process.env.SF_REFRESH_TOKEN
});

// Refresh token kullanarak token yenileme
conn.on(‘refresh’, function(accessToken, res) {
   // Yeni token’ı güvenli bir şekilde saklama
    console.log(‘Access token yenilendi’);
});

CI/CD Pipeline’larında Metadata API Kullanımı

Metadata API, Jenkins, GitHub Actions veya GitLab CI gibi CI/CD araçlarıyla entegre edilebilir:

# GitHub Actions workflow örneği
name: Salesforce Deployment

on:
   push:
     branches: [ main ]

jobs:
  deploy:
     runs-on: ubuntu-latest
     steps:
        – uses: actions/checkout@v2
        – name: ‘Node.js kurulumu’
          uses: actions/setup-node@v2
          with:
             node-version: ’14’

        name: ‘Bağımlılıkları yükleme’
          run: npm install jsforce

        – name: ‘Salesforce Deployment’
          env:
             SF_USERNAME: ${{ secrets.SF_USERNAME }}
             SF_PASSWORD: ${{ secrets.SF_PASSWORD }}
             SF_TOKEN: ${{ secrets.SF_TOKEN }}
             SF_LOGIN_URL: ${{ secrets.SF_LOGIN_URL }}
           run: |
              node ./scripts/deploy-metadata.js

Örnek Kullanım Senaryoları

Senaryo 1: Çoklu Ortam Yönetimi

Birçok organizasyon, geliştirme, test, kalite kontrol ve üretim gibi çoklu ortamlara sahiptir. Bu ortamlar arasında konfigürasyon değişikliklerini yönetmek için Metadata API kullanabilirsiniz:

// Node.js örneği – Ortam bazlı deployment scripti
const environments = {
     dev: {
         username: process.env.DEV_USERNAME,
         password: process.env.DEV_PASSWORD,
         loginUrl: ‘https://test.salesforce.com’
    },
     qa: {
        username: process.env.QA_USERNAME,
        password: process.env.QA_PASSWORD,
        loginUrl: ‘https://test.salesforce.com’
    },
     prod: {
        username: process.env.PROD_USERNAME,
        password: process.env.PROD_PASSWORD,
        loginUrl: ‘https://login.salesforce.com’
     }
};

const targetEnv = process.argv[2] || ‘dev’;
const env = environments[targetEnv];

if (!env) {
   console.error(`Hata: ‘${targetEnv}‘ ortamı bulunamadı.`);
   process.exit(1);
}

// Seçilen ortama bağlanma ve deployment yapma
const conn = new jsforce.Connection({
    loginUrl: env.loginUrl
});

conn.login(env.username, env.password + env.securityToken, (err, userInfo) => {
   if (err) { return console.error(err); }
   console.log(`${targetEnv} ortamına bağlandı: ${userInfo.organizationId}`);

  // Deployment işlemleri…
});

Senaryo 2: Otomatik Konfigürasyon Yönetimi

Standart bir ortam oluşturmak veya tekrarlayan konfigürasyon değişikliklerini otomatikleştirmek için Metadata API kullanabilirsiniz:

// Java örneği – Standart profil konfigürasyonu
public void configureStandardProfiles() {
      Profile adminProfile = new Profile();
      adminProfile.setFullName(“Admin”);

      ProfileObjectPermissions accountPerms = new ProfileObjectPermissions();
      accountPerms.setObject(“Account”);
      accountPerms.setAllowCreate(true);
      accountPerms.setAllowRead(true);
      accountPerms.setAllowEdit(true);
      accountPerms.setAllowDelete(true);
      accountPerms.setViewAllRecords(true);
      accountPerms.setModifyAllRecords(true);

      adminProfile.setObjectPermissions(new ProfileObjectPermissions[] { accountPerms });

      Metadata[] metadata = new Metadata[] { adminProfile };
      SaveResult[] results = metadataConnection.updateMetadata(metadata);

      for (SaveResult result : results) {
              if (result.isSuccess()) {
                   System.out.println(“Profil güncellendi.”);
              } else {
                    System.out.println(“Hata: “ + result.getErrors()[0].getMessage());
         }
   }
}

Senaryo 3: Organizasyon Analizi ve Dökümantasyonu

Metadata API, mevcut bir organizasyonun kapsamlı bir envanterini çıkarmak için kullanılabilir:

// Node.js örneği – Organizasyon envanteri oluşturma
async function createOrgInventory() {
    const metadataTypes = [
         ‘ApexClass’, ‘ApexTrigger’, ‘CustomObject’, ‘CustomField’,
         ‘Layout’, ‘Profile’, ‘PermissionSet’, ‘Flow’, ‘Dashboard’
];

  const inventory = {};

  for (const type of metadataTypes) {
     try {
          const results = await conn.metadata.list([{ type: type }]);
          inventory[type] = Array.isArray(results) ? results : [results];
          console.log(`${type}: ${inventory[type].length} bileşen bulundu.`);
      }  catch (err) {
          console.error(`${type} listelenirken hata oluştu:`, err);
          inventory[type] = [];
    }
}

  // Envanter raporunu oluşturma ve kaydetme
 const report = JSON.stringify(inventory, null, 2);
 fs.writeFileSync(‘org-inventory.json’, report);
 console.log(‘Organizasyon envanteri oluşturuldu: org-inventory.json’);

}

Salesforce Otomasyonunuzun Gücünü Artırın

Salesforce Metadata API, geliştirme süreçlerinizi otomatikleştirmek, organizasyonlar arası değişiklikleri yönetmek ve DevOps uygulamalarınızı entegre etmek için güçlü bir araçtır. Bu rehberde temel kavramlardan ileri düzey tekniklere kadar Metadata API’nin nasıl kullanılacağını inceledik.

API’yi etkili bir şekilde kullanarak, manuel konfigürasyon değişikliklerinden kaynaklanan hataları azaltabilir, deployment süreçlerinizi hızlandırabilir ve geliştirme ekibinizin verimliliğini artırabilirsiniz.

Salesforce geliştirme yolculuğunuzda bir sonraki adım olarak, projelerinizde Salesforce DX araçlarını keşfedebilir veya Metadata API’yi kullanarak kendi özel CI/CD pipeline’ınızı oluşturabilirsiniz.

İlgili Makaleler

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Başa dön tuşu