We zullen een paar onderwerpen behandelen om je leven gemakkelijker te maken, of je nu al managed packages van de tweede generatie gebruikt of dat dit onderwerp nieuw voor je is.
Wanneer u een nieuwe release maakt, kan het veel tijd & moeite kosten, en wanneer het mislukt, geeft het soms niet veelzeggende fouten om u te helpen het probleem op te lossen! Ik zou echt willen dat het meer gedetailleerde foutmeldingen gaf zoals het sfdx deploy commando. Maar dat’s nog niet het lelijkste deel, het wordt nog lastiger wanneer je pakket al is gemaakt en klaar voor gebruik, maar wanneer je het probeert te installeren in je test org, kom je erachter dat er een heleboel functies niet werken zoals verwacht!
Als je deze puinhoop wilt vermijden of er al mee te maken hebt, dan ben je hier op de juiste plaats om te leren van onze uitdagingen en fouten en je onnodige hoofdpijn te besparen.
Apex Toegangsmodifiers
Laten we beginnen met het leren kennen van de verschillende toegangsmodifiers in apexklassen, zodat het je kan helpen kiezen hoe je je code implementeert:
Private
Deze toegangsmodifier is de standaard en betekent dat de methode of variabele alleen toegankelijk is binnen de Apex-klasse waarin deze is gedefinieerd. Als je geen access modifier specificeert, is de methode of variabele private.
Beschermd
Dit betekent dat de methode of variabele zichtbaar is voor alle binnenklassen in de definiërende Apex klasse en voor de klassen die de definiërende Apex klasse uitbreiden. Je kunt deze access modifier alleen gebruiken voor instance methods en member variabelen. Deze instelling is strikt permissief dan de standaard (private) instelling, net als Java.
Public
Dit betekent dat de methode of variabele toegankelijk is voor alle Apex binnen een specifiek pakket.
In Apex is de public access modifier niet hetzelfde als in Java. Dit is gedaan om het samenvoegen van applicaties te ontmoedigen, om de code voor elke applicatie apart te houden. Als je in Apex iets openbaar wilt maken zoals in Java, moet je de global access modifier gebruiken.
@NamespaceAccessible annotation
Voor toegankelijkheid door alle tweede generatie (2GP) beheerde pakketten die een naamruimte delen, gebruik public met de @NamespaceAccessible annotatie. Door de public access modifier te gebruiken in no-namespace packages wordt de Apex code impliciet @NamespaceAccessible.
Globaal
Dit betekent dat de methode of variabele kan worden gebruikt door elke Apex-code die toegang heeft tot de klasse, niet alleen de Apex-code in dezelfde toepassing. Deze access modifier moet worden gebruikt voor elke methode waarnaar moet worden verwezen buiten de applicatie, hetzij in SOAP API of door andere Apex code. Als je een methode of variabele als globaal declareert, moet je ook de klasse die deze bevat als globaal declareren.
We raden aan om de global access modifier zelden of nooit te gebruiken. Applicatie-overschrijdende afhankelijkheden zijn moeilijk te onderhouden.
AuraEnabled Annotatie
De @AuraEnabled annotatie maakt client-side en server-side toegang tot een Apex controller methode mogelijk. Met deze annotatie worden je methoden beschikbaar voor Lightning-componenten (zowel Lightning-webcomponenten als Aura-componenten). Alleen methoden met deze annotatie zijn beschikbaar.
In API versie 44.0 en hoger kunt u de runtime prestaties verbeteren door methode resultaten op de client te cachen met behulp van de annotatie @AuraEnabled(cacheable=true). Je kunt methode resultaten alleen cachen voor methoden die gegevens ophalen maar deze niet wijzigen. Door deze annotatie te gebruiken, is het niet meer nodig om setStorable() aan te roepen in JavaScript-code op elke actie die de Apex-methode aanroept.
In API versie 55.0 en later kun je de annotatie @AuraEnabled(cacheable=true scope='global') gebruiken om Apex methodes te laten cachen in een globale cache.
global met delen klasse TestClass{Je kunt op deze manier naar deze methode verwijzen vanuit een ander pakket in je Lightning Web Component
@AuraEnabled global static void testMethod{} }
import logExceptionLWC van "@salesforce/apex/TestClass.testMethod";
JSON Access Annotation
Eén van de belangrijkste trucs is wanneer je een aangepast model maakt in je apex code en je moet het later misschien serialiseren of deserialiseren, dan moet je zeker de Json Access annotatie toevoegen voor je aangepaste model. Tip: zorg ervoor dat je de annotatie ook toevoegt aan je kindobjecten ;)
Wat is Json Access annotatie? En wat zijn de serialisatie- en deserialisatieopties en overwegingen?
De @JsonAccess annotatie, gedefinieerd op Apex klassenniveau, bepaalt of instanties van de klasse kunnen worden geserialiseerd of gedeserialiseerd. Als de annotatie de JSON serialisatie en deserialisatie beperkt, wordt een runtime JSONException exception gegooid.
De parameters serializable en deserializable van de @JsonAccess annotatie bepalen in welke contexten Apex serialisatie en deserialisatie toestaat.
Je kunt één of beide parameters opgeven, maar je kunt de annotatie niet zonder parameters opgeven. De geldige waarden voor de parameters om aan te geven of serialisatie en deserialisatie zijn toegestaan:
- nooit: nooit toegestaan
- sameNamespace: alleen toegestaan voor Apex-code in dezelfde namespace
- samePackage: alleen toegestaan voor Apex-code in hetzelfde pakket (heeft alleen invloed op pakketten van de tweede generatie)
- always: altijd toegestaan voor alle Apex-code
JSON toegangsoverwegingen
Als een Apex klasse geannoteerd met JsonAccess wordt uitgebreid, erft de uitgebreide klasse deze eigenschap niet. Als de methode toString wordt toegepast op objecten die niet mogen worden geserialiseerd, kunnen privégegevens worden blootgesteld. Je moet de methode toString overschrijven op objecten waarvan de gegevens beschermd moeten worden. Bijvoorbeeld, het serialiseren van een object dat is opgeslagen als een sleutel in een map roept de methode toString op. De gegenereerde map bevat key (string) en value entries, waardoor alle velden van het object worden blootgesteld.
@JsonAccess(serializable='always' deserializable='always') globale klasse FullDetails{ global String fullName {get; set;} global Address adres {get; set;} @JsonAccess(serializable='always' deserializable='always') globale klasse Adres{ global String streetName {get; set;} global String postalCode {get; set;} } }
Referencing Apex Classes from a Managed Package
Wat als je een aantal onverpakte apex klassen maakt in je project en je zou kunnen verwijzen naar een andere apex klasse of een interface die deel uitmaakt van het beheerde pakket? Zorg er gewoon voor dat je deze klassen als globaal instelt en verwijs naar de klasse door <Namespace>.<ClassName>
Genoemde referenties
De gebruikelijke calloutverwijzing zou zijn callout:<NamedCredentialsApiName>, maar als je named credentials gebruikt als onderdeel van je pakket voor je calloutklassen, moet je deze bijwerken naar callout:<NampeSpace>__<NamedCredentialsApiName>
Gesloten app
Als je de connected app component toevoegt aan je pakket, zijn hier de exacte stappen om dat te doen en een aantal veelvoorkomende bugs te vermijden
- Maak een org voor ontwikkelaars
- Ga naar pakketbeheer
- Controleer de beschikbaarheid van de naamruimte en voeg deze toe
- Link de naamruimte-ontwikkelaar org aan je DevHub (als de verbinding niet tot stand komt na het gedeelte van de toestaan toegang popup, wacht dan 10 tot 15 minuten en probeer het opnieuw)
- Ga naar app manager en maak een nieuwe verbonden app
- Wijs volledige rechten of api-, web- en verversingsrechten toe
- Na het maken van de connected app kun je metadata toevoegen in je dx project
<?xml version="1.0" encoding="UTF-8"?> <ConnectedApp xmlns="http://soap.sforce.com/2006/04/metadata"> <developerName>YourNamespace__ConnectedAppName</developerName> <contactEmail>ConnectedAppContactEmail</contactEmail> <label>ConnectedAppLabelName</label> <versie>ConnectedAppVersion</versie> </ConnectedApp>
Als u exact dezelfde stappen hebt gevolgd en tijdens het aanmaken van de pakketversie mislukt het met de foutmelding
ERROR force:package:version:create: <ConnectedAppName>: Het installeren van een app (<ConnectedAppName>) die is verwijderd.
Trust me we've been there, je moet eerst een nieuw pakket maken en dan een nieuwe pakketversie! Om dit te valideren voordat je begint, maak je een nieuw dummy dx-project en maak je een nieuw pakket, voeg je dezelfde verbonden app toe die je al hebt gemaakt, en maak je uiteindelijk je pakketversie aan en laat me weten of dat bij jou werkt!
Rest van Salesforce-onderdelen
Tot slot moet u al uw velden, objecten, triggers, toestemmingssets, aangepaste metagegevens, enz. doorlopen en <Namespace>__ toevoegen
Installatie van beheerde pakketuitdagingen en trucs
Als u een soortgelijke fout tegenkomt waardoor uw pakket in geen enkele omgeving wordt geïnstalleerd, kunt u, in plaats van uren en dagen te spenderen aan het uitzoeken ervan, gewoon die standaard Quick Actions uit uw lay-out verwijderen en ze opnieuw toevoegen zodra het pakket met succes is geïnstalleerd.
(Objectnaam-Layout) In veld: QuickAction - geen QuickAction met de naam NewCase gevonden
(ObjectName-Layout) In veld: QuickAction - geen QuickAction met de naam NewTask gevonden
(ObjectName-Layout) In veld: QuickAction - geen QuickAction met de naam LogACall gevonden
Component [flexipage:filterListCard] attribuut [filterName]: Fout bij het ophalen van filter [My_ChatterGroups] voor entiteit [CollaborationGroup]
Een andere om over na te denken: als uw broncode afhankelijk is van ingebouwde Salesforce-componenten, zorg er dan voor dat u toegang geeft tot die componenten als onderdeel van uw pre-deploymentstappen voordat u de pakketversie installeert. Zoals hier het inschakelen van omni channel.
Uw org heeft geen toegang tot component runtime_service_omnichannel:omniWidget.
Tot slot, als je standaardValueSets in je broncode hebt en de metadata van je pakketversie daarvan afhankelijk is, zorg er dan voor dat je die value sets uitrolt als pre-deployment stap vóór de installatie van de pakketversie. Zoals hier, het implementeren van aangepaste status keuzelijst waarde met de naam TestValue.
Component [lst:dynamicRelatedList] attribuut [adminFilters]: TestValue is geen geldige picklistwaarde.
Je kunt Metadata Dekking Documentatie raadplegen om te weten welke componenten packageable zijn!
Wij delen graag alle nuttige informatie en raden u aan meer te weten te komen over onze impact op de releasecyclus in Salesforce
Pland een demo om meer te weten te komen over hoe Serpent uw Salesforce DevOps strategie vandaag nog kan verbeteren! Serpent van Tekunda biedt een aantal uitstekende tools om uw DevOps-teams te helpen, waaronder ingebouwd versiebeheer, systemen voor continue implementatie en vrijgave, tools voor samenvoegen en tal van verschillende testtools.