© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2022
L. Harding, L. BaylissSalesforce Platform Governance Methodhttps://doi.org/10.1007/978-1-4842-7404-0_7

7. Apex, Visualforce & Lightning: Phase F

Lee Harding1   and Lee Bayliss2
(1)
Clayton-le-Woods, UK
(2)
Clifton, UK
 

This phase of the Salesforce Platform Governance Method focuses on the programmatic side of the Salesforce platform, which includes the Apex, Visualforce, and Lightning development capabilities.

Overview

The Salesforce platform offers a large amount of configurability and automation without the need to resort to a traditional programming language. However, some projects will inevitably have requirements that can be best met by using the Salesforce platform’s programmatic features.

Your organization may have policies in place to help guide projects as to the appropriate time or reason to choose a programmatic solution over the declarative options available. Given that Flow is rapidly growing into a viable alternative to developing Apex code, those policies may be updated regularly. As shown in Figure 7-1, this phase is broken down into sub-phases to help your governance team provide focused feedback to your projects.
Figure 7-1

The Salesforce Platform Governance Method: Phase F

As with previous phases, let’s start by defining what we mean by Apex, Visualforce, and Lightning so that we are clear as to what we are governing. In the context of the Salesforce Platform Governance Method, we will use the Salesforce definitions, as they are Salesforce technologies. First, Apex:

“Apex is a strongly typed, object-oriented programming language that allows developers to execute flow and transaction control statements on the Lightning platform server in conjunction with calls to the Lightning Platform​ API. Using syntax that looks like Java and acts like database stored procedures, Apex enables developers to add business logic to most system events, including button clicks, related record updates, and Visualforce pages. Apex code can be initiated by Web service requests and from triggers on objects.”

—Salesforce1

Next, we’ll define Visualforce as the following:

“Visualforce is a framework that allows developers to build sophisticated, custom user interfaces that can be hosted natively on the Lightning platform. The Visualforce framework includes a tag-based markup language, similar to HTML, and a set of server-side ‘standard controllers’ that make basic database operations, such as queries and saves, very simple to perform.”

—Salesforce

Finally, we will define the Lightning term as the following:

“The Lightning Component framework is a UI framework for developing single page applications for mobile and desktop devices.

As of Spring ’19 (API version 45.0), you can build Lightning components using two programming models: the Lightning Web Components model, and the original Aura Components model. Lightning web components are custom HTML elements built using HTML and modern JavaScript. Lightning web components and Aura components can coexist and interoperate on a page.”

—Salesforce

If your project team has delivered a component or solution using the programmatic capabilities of the Salesforce platform, it will be using all or a combination of the following:
  • Apex

  • Lightning component (Web or Aura)

  • Visualforce

Your governance team will need to understand some of the nuances of these technologies, especially when looking at the future usage of the Salesforce platform and recognizing that reusable components may be elevated to enterprise level from a project level.

As with all source code–driven development, your project team should seek to manage the software assets properly, and your governance team will look to understand how this is achieved. A more mature organization may have an existing source code repository and version control system in place. For those embarking on their first Salesforce application development, this is something that you may be looking to implement for the first time.

The following provides a brief description of the Salesforce platform technologies, but by no means serves as a replacement for the thorough understanding of these technologies that will be required to properly govern this part of the Salesforce Platform Governance Method. As such, your governance team should look to call upon experts within your organization who can help review the solutions developed by your project teams in their specific areas.

Visualforce

Visualforce uses a markup language that is very similar to HTML for designing pages, and then Apex code for supporting database operations and business processes. Typically, there are four parts to a Visualforce solution, as follows:
  • Visualforce Page – A markup language like HTML is used to design the content and layout of the page or user interface.

  • Custom Controller – Apex code will process all the server-side operations implemented within the Visualforce page.

  • JavaScript – Optionally used to perform any client-side processing and user interface manipulations.

  • Apex Extension – Further processing can be optionally achieved in Apex extensions, which are not supported within a standard controller.

Apex

Apex is a programming language that is very similar to Java. It is a strongly typed, object-oriented language that allows developers to execute complex processes to leverage the Salesforce platform’s abundant APIs. Apex can be initiated from triggers on objects, where data changes or database actions can trigger Apex code to be executed, or from a Web service.

Apex is executed server side and can open up complete flexibility in terms of what can be achieved on the Salesforce platform. It is used in the platform in two areas:
  • Apex Triggers – Apex triggers can be configured to perform processing on data before or after changes to records,; for example, inserting a new record could initiate an Apex trigger.

  • Apex Classes – Classes are a template to create Apex objects. Classes contain methods, variables, other classes, and so forth. Using Apex, complex business processes can be accomplished that can not only operate upon internal Salesforce platform data, but also make call-outs to external systems.

Developing a program in Apex is no different to developing in any language, with coding standards and naming conventions in place so that any developer feels at home debugging or enhancing code developed by previous programmers. However, one area where Apex does differ from most other programming languages is that unit testing is enforced. The Salesforce platform will not allow Apex code to be deployed to your production org without your project’s Apex test classes exercising at least 75% of the Apex code you are deploying. This is considered good practice in most other programming languages, but is enforced on the Salesforce platform due to the platform’s multi-tenancy nature.

The need to develop unit test classes in Apex is sometimes overlooked by inexperienced developers, as this is not enforced when actually developing on your sandboxes.

This need for Apex test classes adds additional overhead to the governance process because it is additional code that must be reviewed against the development standards, and of course it will need to be managed and maintained in exactly the same way as the rest of your project’s Apex code.

Lightning Components

When Salesforce introduced the Lightning user interface (UI) for its core platform (often referred to as Salesforce, SalesCloud, ServiceCloud, or CRM), it also delivered a new technology to allow developers to build bespoke components for that UI for use in their own applications alongside those delivered by Salesforce.

Lightning components can be developed using two different technologies. The original used what Salesforce called the Aura framework and was introduced by Salesforce around 2013. This open source framework essentially provided the features and functions that underpinned Salesforce’s new Lightning UI. This version of Aura was archived in 2019, although it is still supported by Salesforce. It could be considered a legacy solution even though this is not the position taken by Salesforce.

Aura was replaced by Lightning Web Components (LWC) around 2019, which uses the current standards in Web technology. You could consider Aura as a proprietary JavaScript framework while LWC uses standard JavaScript capabilities. As such, developing solutions using LWC is a more familiar experience to Web developers than using Aura was. Additionally, some might say that LWC performs much better than Aura-based components .

As of the writing of this book, both Lightning component solutions are available to your projects, and they can interoperate. However, while you can embed an LWC within an Aura Lightning component, you cannot do the opposite because of the bespoke nature of the Aura framework.

Design and Functionality

As shown in Figure 7-2, design and functionality is the first of the sub-phases in the Apex, Visualforce, and Lightning governance phase.
Figure 7-2

Phase F: Apex, Visualforce & Lightning - design and functionality

Govern the continuum of UI options actually used against those available on the platform (buttons, mashups, Canvas, Visualforce pages, and Lightning components)

The Salesforce platform offers more configurability than most people can probably remember, and the number of ways in which to initiate bespoke functionality is no exception.

As mentioned previously, Lightning components offer nearly unlimited possibilities, with Lightning Web Components being made even more extensible with the introduction of standard JavaScript libraries such as chart.js, among countless others. However, your governance team will need to understand why a bespoke component was built when a standard component may have delivered the same business outcome. This is important because your bespoke solution will require ongoing maintenance and support, potentially needing to be revisited in the future as the Salesforce platform progresses in its relentless release cadence. In comparison, an inbuilt feature once configured will more than likely require less support and maintenance in the longer term.

This is especially true when integrating with external systems. It is sometimes easy to think only of the data level of integration, making call-outs as necessary when data is required and building a bespoke user interface to interact with that data. An alternative may be to deliver the external system as a Canvas app embedded within the Salesforce UI and then have Salesforce interact with that external application’s user interface. Of course, this is not always possible, or perhaps more often than not a complete set of functions cannot be delivered to the end user due to limitations in the external system’s user interface.

If the necessary knowledge cannot be found within your governance team, the team will need to call upon the appropriate resources to learn what is possible on the Salesforce platform versus what has been proposed by the project team. Ultimately, your governance team is trying to protect your organization from unwanted cost in the longer term as a result of having components developed that basically replicate existing standard functionality.

Caution

Our experience has shown us time and again that this basic governance step is not taken. Many organizations that we have worked with over the years have duplicated built-in functionality, either because of unfamiliarity with the Salesforce platform or because the organization has a team of developers that “always do it that way.” However, all of these organizations get frustrated when every new release of the Salesforce platform forces them to revisit their bespoke code. If you are in an organization that is still using the “Classic” user interface because migrating to Lightning is not possible, it is likely you are dealing with this situation.

Govern the sharing and visibility model in code solution

The Salesforce platform will run Apex in the system context, which basically means that it does not consider the user’s permissions when executing the code. This makes sense in most cases because the code your project team has developed may need to operate across the entire data set and not just the data visible to the user.

Your governance team will need to pay close attention to the sharing and visibility model that is utilized within your code. The importance of data visibility was highlighted in Phase D of the Salesforce Platform Governance Method and as such should be your governance team’s initial attempt at governing this area. However, during this phase your governance team is looking for evidence that what was uncovered during the Phase D assessment has in fact been implemented.

Govern the code against security best practices to ensure all Visualforce and Apex code is developed per OWASP standards

As with all platforms that provide a programmatic solution to tailoring end-user functionality, there is always the possibility of inadvertently exposing your organization to security risks. The Open Web Application Security Project (OWASP) provides a set of standards that should be adhered to when developing an application that is exposed to the Web. As the Salesforce platform is an SaaS platform, it is accessible from the Web (in fact, this is the only way it is accessible), and as such any code that is developed by your project is also exposed. Of course, the Salesforce platform offers guard rails when you are using declarative and basic configuration, but once you move into developing on the platform using Apex or other technologies you are opening yourself up to vulnerabilities unless the proper standards are applied.

OWASP provides a top ten Web application vulnerability list, which is just as applicable to the Salesforce platform as any other platform used to develop applications. At the time of writing this book, the top ten vulnerabilities according to OWASP2 are as follows:
  • Injection

  • Broken authentication

  • Sensitive data exposure

  • XML external entities

  • Broken access control

  • Security misconfiguration

  • Cross-site scripting

  • Insecure deserialization

  • Using components with known vulnerabilities

  • Insufficient logging and monitoring

Given this list, it is easy to see how your project could run into some issues that need to be addressed.

Caution

Security misconfiguration is a common problem. There are a number of causes of this. Inexperienced Salesforce administrators might think providing everyone full access is easy and a “quick fix” to some problem. More often than not, the analysis around personas isd completely overlooked or a last-minute “guess.” Understanding the correct access (remembering the least-privilege principles) is paramount to the ongoing security of your data and hence your business.

Your governance team should be aware of the OWASP standards or their own organization’s standards to be assured that the project has considered and implemented the proper controls for their bespoke code.

Tip

Webhooks have become a popular solution that sends a “nudge” from an external system that an action has taken place that may be of interest to your application. This is mostly implemented using a public site within the Salesforce platform that calls an Apex class automatically with no authentication. Make sure you have secured that Apex class.

Govern the object-oriented design principles and design patterns that were adhered to when developing the solution (Singleton, etc.)

Apex is an object-oriented language and as such adheres to object-oriented design principles. Lightning components use JavaScript, which is an object-based language; however, some of the principles around object-oriented design still apply.

Note

Object-oriented development was introduced circa 1966, many decades before the Salesforce platform was even thought about, so it is not something that is new. However, it is surprising how many developers use an object-oriented programming language without fully understanding the principles of object-oriented programming.

Your governance team should have a thorough understanding of object-oriented design or access to resources that can perform this governance step on their behalf.

The main thrust of this step is for your governance team to determine whether the appropriate design principles have been applied to the project’s development. Have classes been appropriately used and designed, with appropriate methods encapsulated using public or private? Have attributes also been suitably encapsulated?

A good indication that your project’s development team does not fully understand the principles of object-oriented design is the misuse of or complete disregard for the following:
  • Inheritance – child classes inherit data and behaviors from a parent class

  • Encapsulation – containing information in an object, exposing only selected information

  • Abstraction – only exposing high-level public methods for accessing an object

  • Polymorphism – many methods can do the same task

The misuse of these principles can be quite easy to identify. If your project is duplicating functionality within several classes, inheritance has probably been overlooked, or possibly abstraction should have been considered. Declaring every attribute and method of a class public can indicate the encapsulation was not fully understood. If many methods have been created that have different names but fundamentally perform similar functions, just using different attributes, then polymorphism is possibly misunderstood.

There are other aspects of the Apex language that could also lead to bad object-oriented design, such as the use of static or the inadvertent creation of a singleton.

Your governance team is really looking at the maintainability of the programs developed by your project’s development team. Object-oriented design principles are fundamentally designed to simplify the reusability of functionality, while protecting the inadvertent modification of that reusable code. This should provide your project teams with accelerated delivery, while minimizing repeated testing.

Tip

It is very common to see a single Apex class with many functions that are performing unrelated processes. While this is more common than is desirable, it does not break the Salesforce platform. Adhering to object-oriented principles is something that is helpful to your organization and that ultimately will deliver a more maintainable code base with lower occurrences of repeated code, which on a platform with a limited number of resources available to your projects (including the lines of Apex code) is always a good thing.

Govern the appropriate use of the Model-View-Controller pattern

The Model-View-Controller pattern is commonly used for developing user interfaces that divide a program into three interconnected components. This is done to separate internal representations of data from the ways the data can be presented to and accepted from the end user.

The model represents the data and its storage, while the controller represents the processing applied to that data, such as a business process. The view is the representation of the data to the end user.

The Model-View-Controller design pattern can help you gain reusability from your investment in developing code. Your projects can deliver multiple user interfaces onto a single controller without having to re-engineer that controller.

Visualforce enforces the Model-View-Controller pattern in that it has a mark-up language very similar to HTML that controls the user representation, which is the view. A controller represents the processing of the data inputted by an end user before it is updated in an object, which represents the model.

Using Lightning components, whether Aura or LWC, the programmer could bypass this pattern, as they could in theory make a direct call from the client to a back-end server-side API, as an example.

Your governance team should be familiar with the MVC design pattern and look for instances where this pattern should have been used. Obvious examples breaching this design pattern are Lightning components that perform business logic, handle the display to the end user, and then push the data model directly to a basic Apex server-side class that really doesn’t do anything.

Govern any Apex controllers against the technical standards (extensions to standard controllers and custom controllers)

All Salesforce platform objects come with a pre-built standard controller, even custom objects. These standard controllers provide the basic functionality that is required by the Salesforce user interface to interact with the object that the standard controller is associated with. For example, if you hit the Save button on an account using the standard Salesforce user interface, the behavior will be the same as if you had your own button within your Visualforce page that triggers a save. You associate the appropriate controller within the Visualforce markup.

As you would expect, the Salesforce platform allows your project teams to create their own custom controller or extend a standard controller.

The main difference between a custom controller and an extension to a standard controller is that your project team will need to develop all the functions it requires within a custom controller, whereas by extending a standard controller, the project inherits the standard functions and then can apply additional functions.

Tip

Remember that as with all Apex code, controllers will run in the system context and will not take user permissions into account unless explicitly stated.

Your governance team must be capable of reviewing the use of extended and custom controllers to determine whether they have been used appropriately. Additionally, your governance team should be assured that data visibility and access have been appropriately considered, given the system context within which Apex code normally executes.

Additionally, your organization may have guidelines and standards to adhere to. If your project teams are building many custom controllers, your governance team will need to consider appropriate standards for naming the functions within those controllers. From a maintenance perspective it would not be wise to have each project use different standards.

Govern the usage of custom settings and synchronous vs. asynchronous patterns, and all the available execution contexts (e.g., batch, trigger, callout, etc.)

Your project may have used custom settings to store configuration information or perhaps credentials for authentication with external systems. Your governance team should review the need for custom settings and the purpose behind the decision; for example, if credentials are being stored, why was this preferred over the use of a named credential?

In the main, custom settings provide some flexibility in terms of how the custom setting data relates to the current user or otherwise. Additionally, when creating sandboxes, the custom settings data is not replicated. Custom settings are effectively a custom object in terms of the Salesforce metadata and should follow your organization’s naming conventions and standards.

As with most modern platforms, the Salesforce platform allows code to be executed synchronously and asynchronously. The main difference is that when code is executed asynchronously the code that triggered the asynchronous code will continue to execute regardless of what the triggered code is doing.

Your governance team will need to assure themselves that the project team fully understands the implications of this, especially in the context of making call-outs to external systems. Additionally, the synchronous code should be reviewed to understand whether this is constructed in the correct manner. If the user is kept waiting due to synchronous code, this is possibly not going to be a great user experience. Additionally, the Salesforce platform will not allow Apex code to run continuously, but rather will timeout long-running processes. Your governance team will need to know whether the project team has taken these issues into account, especially when making external calls, where response time is not always guaranteed.

The Salesforce platform can run Apex in a number of contexts. Each context introduces limitations and requires some awareness of what is possible for the developer when constructing code. For example, you cannot perform Data Manipulation Language (DML) statements before making a call-out to an external system, which might be frustrating to some, especially when multiple call-outs are made and it is desirable to write the data into Salesforce objects.

Additionally, while the Apex code is running in a batch context, your developers are restricted in the number of DML statements they can perform. Therefore, performing DML within loops for Apex that are intended for batch execution is not acceptable. Your governance team should be looking for assurance that the project team has taken the correct steps to “bulkify” their Apex code if it is destined for execution in a batch context.

Apex triggers are a powerful solution to performing additional processing before or after data is inserted, updated within, or deleted from the Salesforce platform. In many cases, the same actions can be performed using Flow or Process Builder. Your governance team should be assured that your project team is using triggers appropriately, and not diluting the implementation across multiple platform capabilities.

Tip

It is very easy to use multiple Salesforce platform solutions to deliver similar functionality. Triggers could be considered one of these areas. It is wiser to standardize your usage of Flow, Process Builder, and triggers (or any other platform automation) so that all your project teams and ultimately the developers know what the appropriate use is. This will avoid their having to look in several places to make changes, or needing to debug trigger-related functionality.

If Apex triggers are a preferred solution to performing actions based on a specific set of circumstances, your governance team should recommend using a trigger framework. This is especially the case if multiple project teams are looking to add trigger code to a number of standard or enterprise objects. This will avoid projects’ clashing with one another in code, as well as make sure that each project’s trigger code is discrete.

Govern the usage of batch Apex and the flex queue

As previously mentioned, your governance team should focus its attention on any batch Apex delivered by the project team. Your governance team should pay close attention to the following:
  • Any batch job that is invoked from a trigger. Your project team must be able to assure your governance team that the trigger will not add more batch jobs than the allowable limit.

  • The actual execution timeframe requirement. Salesforce only places the batch job in the queue.

  • Any stateful requirements. Instance member variables are reset to their initial states at the beginning of each transaction unless specified.

  • The use of @future. Methods declared with the @future decorator are not allowed to be called from batch Apex.

  • Email notifications for running batch Apex jobs, especially if the batch Apex is part of a managed package.

  • Filter the AsyncApexJob object records. With every 10,000 AsyncApexJob records, Apex creates an AsyncApexJob record of type BatchApexWorker for internal use; your project should filter these out of any queries.

  • Testing has considered governor limits and ensured that the batch has completed before continuing testing.

  • Sharing recalculation. The execute method should delete and then recreate all Apex-managed sharing for optimal sharing accuracy.

  • Any Salesforce service maintenance downtime. Running batch jobs are rolled back and restarted during maintenance.

  • The number of batches your project will create. Having more than 2,000 unprocessed requests from a single Salesforce org causes additional requests from the same Salesforce org to be delayed.

  • Minimize call-out times and tune queries as much as possible. Your project should make sure the batch jobs execute as quickly as possible. Longer executing batch jobs will delay other queued batch jobs.

Developing batch processes take careful planning and consideration regarding the number of batch jobs created and the size of each of those batch jobs. It is very easy to hit issues in production if the amount of data being processed has not been considered carefully.

Govern the Apex / Visualforce solution against the governor limits

As with all aspects of the Salesforce platform, governor limits apply to Apex and Visualforce, perhaps even more so. The governor limits for Apex and Visualforce have a larger impact on the execution of your code than does a consumption of resources within a 24-hour-type limit, as seen in other limitations of the platform.

Your governance team should have a good understanding of the main governor limits that commonly affect Apex and Visualforce, and with Apex, the contexts in which the Apex is being used.

Salesforce categorizes Apex governor limits as follows:
  • Per-Transaction Apex Limits

  • Per-Transaction Certified Managed Package Limits

  • Lightning Platform Apex Limits

  • Static Apex Limits

  • Size-Specific Apex Limits

  • Miscellaneous Apex Limits

Visualforce limits are slightly simpler than the Apex limits, and are mainly focused on the number of records the Visualforce page is dealing with or the amount of data.

Your governance team is basically looking to be assured that the project team has made a concerted effort to understand the use of the Visualforce and Apex code that they have developed and that it will accommodate those use cases. Additionally, your governance team will want to understand the edge cases that the project team has considered so that it is clear as to when problems may be seen in the production environment. This at least will give the operations teams something to monitor, and they can raise the appropriate concern if production workloads are edging toward causing problems with the project’s implementation.

Govern the order of execution of transactions within the platform (specifically against pre-existing triggers)

The Salesforce platform can have numerous automation processes running when something happens to an object. This could be due to data changes or the insertion of a new object record. As you would expect, Salesforce has implemented an order of execution to the processes that can be triggered by changes occurring on the platform.

The order of execution is important as it determines what Salesforce processes will be triggered and in what order. When a record is saved with an insert, update, or upsert statement, Salesforce performs the following events in order:
  1. 1.

    Load the record.

     
  2. 2.

    Run system validation to check the record for page layout–specific rules, field definition, and maximum field length.

     
  3. 3.

    Execute flows that make a “before-save” update.

     
  4. 4.

    Execute all before triggers.

     
  5. 5.

    Run most custom validation rules.

     
  6. 6.

    Execute duplicate rules.

     
  7. 7.

    Save the record to the database without committing the data.

     
  8. 8.

    Execute all after triggers.

     
  9. 9.

    Execute assignment rules.

     
  10. 10.

    Execute auto-response rules.

     
  11. 11.
    Execute workflow rules.
    1. a.

      If there are workflow field updates, then update the record again.

       
    2. b.

      If the workflow field updates introduced new duplicate field values, execute duplicate rules again.

       
    3. c.

      If the record was updated with workflow field updates, fire before and after update triggers one more time (and only one more time) in addition to standard validation.

       
     
  12. 12.

    Execute processes and flow.

     
  13. 13.

    Execute escalation rules

     
  14. 14.

    Execute entitlement rules.

     
  15. 15.

    Execute record-triggered flows that are configured to run after the record is saved.

     
  16. 16.

    If the record contains a roll-up summary field or is part of a cross-object workflow, perform calculations and update the roll-up summary field in the parent record. Parent record goes through save procedure.

     
  17. 17.

    If the parent record is updated, and a grandparent record contains a roll-up summary field or is part of a cross-object workflow, perform calculations and update the roll-up summary field in the grandparent record. Grandparent record goes through save procedure.

     
  18. 18.

    Execute Criteria-Based Sharing evaluation.

     
  19. 19.

    Commit all DML operations to the database.

     
  20. 20.

    Execute all after-commit logic, such as sending email.

     
The after commit logic can consist of a number of processes that require the order of execution to be completed before they can be executed. These processes are as follows:
  1. 1.

    Send all emails.

     
  2. 2.

    Execute asynchronous Apex (@future methods).

     
  3. 3.

    Execute asynchronous Sharing Rule processing (for >25,000 records).

     
  4. 4.

    Outbound messages are placed in the queue.

     
  5. 5.

    Calculate index, such as search index.

     
  6. 6.

    Render file previews.

     
  7. 7.

    Publication of platform events (if configured).

     

The order of execution can create a lot of confusion if it is not clearly understood, and can generate many hours of debugging if the results your project team expects are not what is being experienced.

Your governance team cannot change any of these things, but what is clear is that the order of execution should be considered. Your governance team will be looking for assurance that the project team understands the implications of this order and how it affects their solution. Specifically, your governance team should be asking the project team the following:
  1. 1.

    Has the project team fully understood any changes that might have occurred with each release of the Salesforce platform?

     
  2. 2.

    Has the project team understood the details behind the order of execution?

     
  3. 3.

    Has the project team adhered to a “rule of thumb,” such as one trigger, one process per object?

     
  4. 4.

    Do the project team and operations team understand how to use the debug log to troubleshoot if required? Pay close attention to “***CLOSE TO LIMIT***” debug log entries.

     
  5. 5.

    The project team should avoid situations that could cause a loop in the order of execution; if unavoidable they should be clear of the implications.

     
  6. 6.

    Your project team should consider the use of trigger.old with care.

     

Lastly, your governance team should be assured that your project team has performed the relevant testing, taking into account edge cases and with sufficient data volumes.

Govern the quality of test coverage (required for production deployment, call-out testing is a special case)

Test coverage is critical to the successful deployment of your project’s Apex code. As mentioned previously, the Salesforce platform enforces test coverage on Apex code. Your project’s Apex code must reach a test coverage of 75% before it is allowed to be deployed into the production org.

Tip

It is good practice to take a test-driven development approach. You cannot avoid creating test classes and meeting the 75% test coverage requirement. Your project team should consider the test classes just as important as the business logic they are implementing within the Apex code. Do not leave this until the last minute. Integrate your test class development with your development plan and treat it as equal to any other code you develop. Also, remember you are not trying to reach 75%—it is not a score to obtain. You are fundamentally trying to test your code.

Your governance team should review the test coverage results from your project’s test deployment. Where code has not been covered by the test classes, your governance team should review to understand whether this is acceptable or not. Where call-outs are made, the project team should put in additional effort to simulate the endpoints in the call-out.

Ultimately, your governance team is looking to understand whether the project has taken the development of Apex test classes seriously, or simply manufactured tests to meet the 75% code coverage requirement.

Govern the approach to error/exception handling

Most programming code includes a significant amount of error and exception handling. It is widely accepted that up to 90% of a program’s code will be error and exception handling code rather than business logic. The Apex programming language is no different.

Your governance team will need to be assured that the project team has implemented sufficient error and exception handling within its code so that the end user does not experience errors and therefore report them to the operations team.

As an example, try/catch blocks should be placed around any SOQL. It is easy during development to assume that a consistent result will be seen, given the limited data most development environments have. However, once the code is deployed into the production org, it is often the case that issues arise because the developer made certain assumptions and therefore did not properly check for error conditions.

Tip

Using the LIMIT 1 on SOQL to bring back a single object and then perform processing on that object is a great shortcut, but remember that your project is relying on a single object’s always being returned, which might not always be the case.

Your governance team should be wary of any hard coding within the Apex code; for example, making assumptions around the name of a RecordType when creating a new object record of a certain type.

Equally, your test classes (as discussed earlier) should be testing that error and exception handling has been implemented correctly.

Performance and Scalability

As shown in Figure 7-3, performance and scalability is the next sub-phase on which your governance team should focus.
Figure 7-3

Phase F: Apex, Visualforce & Lightning - performance and scalability

Govern that performance and scalability best practices have been considered within Visualforce pages and Apex code (performance profiling, use of static resources)

The Salesforce platform comes with a few tools that are at your project team’s disposal to help them understand the performance and scalability of the Visualforce pages and Apex that they have delivered. The basic tools are shown in Table 7-1.
Table 7-1

Performance & Scalability Tools

Tool

Description

The Developer Console

The original “go to” tool for all developers that didn’t want to use the Eclipse IDE. The developer console is still heavily used today, but Visual Studio Code and its extensions are rapidly catching up. However, as the developer console is part of the Salesforce platform, it is easy to access and requires no configuration or setup. The developer console provides a number of panels dedicated to analyzing performance. Based on detailed execution logs, which you can open by using the Log Inspector associated with the Logs tab, you can view the graphical timeline of the overall request, the aggregated performance of an operation, and statistics on governor limits, as well as drill down to the executed units.

Debug Logs

A debug log records database operations, system processes, and errors that occur when you execute a transaction. The system generates a debug log for a user every time that user executes a transaction that is included in the filter criteria. The level of detail each log contains can be adjusted. Although the debug log files appear as plain text, it is difficult to interpret their raw log lines. If your projects are using Visual Studio Code as the main development tool, a number of extensions exist that can analyze Salesforce debug logs.

Workbench

Workbench is a Web-based suite of tools available from the developer community. Designed for administrators and developers, this tool allows you to describe, query, manipulate, and migrate both data and metadata in the Salesforce platform directly in your Web browser. Workbench also provides many advanced features for testing and troubleshooting the Salesforce platform’s APIs.

Architecture Development Center

The Architecture Developer Center is a library of best practices for architecting sound implementations on the Salesforce platform. On this page, your projects can find links to many white papers, webinars, and blog posts related to performance optimization. These resources can help your projects determine what to look for when performance profiling their application, as well as see how to apply best practices to overcome performance-related challenges.

Your governance team is looking to be assured that the project team has taken the time to consider and test the performance of its application. Your project team may be using the standard tools mentioned previously, or your organization may have invested in alternatives. Whatever solution your project teams have available to them, performance testing—similar to the unit testing of Apex code—should be a key deliverable in your projects.

Your governance team should look to the project team to provide evidence that such testing has occurred and to deliver a report that details the outcomes of your project team’s testing efforts. Your performance test report should contain the details shown in Table 7-2.
Table 7-2

Performance Test Report Contents

Area

Description

Governor limits analysis

The project team should be providing analysis of its execution logs to highlight the LIMIT_USAGE keyword, demonstrating that there are no areas that are close to reaching any governor limits.

Sharing settings

The project team should demonstrate that they have iterated their performance testing to consider users of differing roles coupled with a reasonable data volume to identify that sharing calculation overheads are not an issue. Testing as a system administrator with full access to all data effectively bypasses any sharing recalculation as the user already has full access.

Database caching

The project should provide its performance test results, ideally with a baseline benchmark with no cache in effect. The project should run a test several times, demonstrating the effect of caching and the initial overhead that the user will experience.

Indexes

Your project is not able to force the Salesforce platform to use an index; however, the project can demonstrate that there is a performance improvement by swapping out index fields in a query with custom fields that are not indexed. This creates a baseline performance for comparison and evaluation of the index’s effect of the query.

Load testing

Load testing, where multiple concurrent users are simulated on the Salesforce platform, is a key part of performance testing. As your project team has no real control over the performance of the Salesforce platform beyond its own customizations, the team is really looking to understand any impact on governor limits, such as long-running Apex (more than five seconds). Your project will need to raise a support case with Salesforce before performing load tests.

As with most governance roles for any other platform, your governance team is trying to establish that the project team has undertaken its due diligence in terms of understanding the impact its application has on the Salesforce platform given the potential usage it is going to see.

It may be that your project team has created an application for a specific set of users at a specific scale, or at least is comfortable that the application will work as expected up to a particular usage. This is a good approach in setting boundaries for application usage. Taking this approach could trigger future testing if, for example, your company acquires another and you are suddenly increasing your user base.

Govern the Apex and Visualforce performance to include LDV scenarios (Pagination, JavaScript remoting)

Your governance team may come across a project that uses large data volumes (LDVs); however, the definition of a large data volume is not exact. Your project team may be looking to create tens of millions of records with a relatively simple custom object, or hundreds of thousands of records with a very complex object.

Your governance team is looking to understand the steps your project team has taken to accommodate its large data volumes. In most cases, when dealing with LDVs, it is normal for processes to take longer to execute; after all, there are many more records that could be affected by any changes that your project’s users make or other processes that the project creates.

The Salesforce platform provides some features that your project team can take advantage of when dealing with large data volumes. JavaScript remoting provides your developers with the ability to create asynchronous calls to your Visualforce controllers so as to lazy-load data, or load data as it becomes relevant to the end user. Pagination allows your project to request pages of information rather than everything, providing your end users with the ability to move through pages of data at their own pace, rather than long lists of data that take a while to load.

Your governance team will be looking for assurance from the project team that where large data volumes are expected, the project has taken steps to provide a means for the end user to interact with that data in a sensible manner.

Govern the use of external web technologies and complementary UI technologies

With Visualforce and Lightning components your project teams can leverage libraries that are available from multiple developers. Lightning components have made it easier than ever to add libraries to the Salesforce platform’s user interface to create a user experience that end users now expect from a modern Web-based application.

Your governance team will need to pay close attention to the external libraries and technologies that your project team has utilized and from where these external libraries and components have come. The AppExchange is a great source for Lightning components that can be “plugged” into your project’s Lightning pages. Additionally, if your project team is building its own Lightning components, then third-party JavaScript libraries may be of use to provide specific features and functionality.

Although your governance team is not going to try to restrict what the project team is attempting to deliver, it will need to be assured that the proper commercial and support requirements have been reviewed across the entire project’s solution. Where a third-party JavaScript library is in use, the project team should be able to provide assurance that the library complies with your company’s commercial and security requirements. It is likely that your supplier or purchasing department may need to be involved to put the correct procedures in place to pay any subscription costs for using the third-party components and libraries.

Your security team may need to review the data policy of the third party to be assured that there is no possibility of data leakage and that the third party is a reputable organization.

Additionally, your governance team will be looking to understand any support requirements for business needs across all the components that are being used in the development of the solution.

Maintainability and Reuse

As shown in Figure 7-4, maintainability and reuse is the next sub-phase on which your governance team should focus.
Figure 7-4

Phase F: Apex, Visualforce & Lightning - maintainability and reuse

Govern multi-language support and determine the appropriate solution has been used to support globalization

Your governance team will need to understand the language capabilities of the Salesforce platform.

Depending on your company’s language requirements, your project team has three options in terms of language support on the Salesforce platform, as shown in Table 7-3.
Table 7-3

Multi-language Support

Area

Description

Fully supported languages

Languages in this category are fully supported by the Salesforce platform. All Salesforce features and user interface text appear in the chosen language.

End-user languages

Provide a solution for an end user to select a language other than the default. Salesforce provides translated labels for all standard objects and pages, except admin pages, Setup, and Help. Unsupported labels appear in English.

Platform-only languages

In situations where the Salesforce platform does not provide a default translation, platform-only languages can be used to localize apps and custom functionality that your project builds on the Salesforce platform. Your project team can translate items such as custom labels, custom objects, and field names. Your project team can also rename most standard objects, labels, and fields. Informational text and non-field label text aren’t translatable.

To provide further flexibility, the Salesforce platform provides a tool called the translation workbench. When enabled, this tool allows your project team to specify languages for translation, assign translators, and manage those translations through the workbench or bulk translation.

As language support can have a great effect on the end-user community, your governance team will need to be assured that the project team has understood the language requirements from the business, then compared those requirements to the capabilities of the Salesforce platform given the three options mentioned previously. If additional work is required to provide translations, then additional testing will be required. Your business will also need to understand what is possible and any limitations for specific languages.

Govern the options and techniques used to make programmatic components maintainable and reusable on the platform (custom settings, skeleton templates, custom metadata types)

Creating maintainable and reusable components is the desire of nearly all development projects. It is unlikely that any programmer sets out to deliver code that is impossible to maintain. However, not all programmers intend for their programs to be reusable.

Creating reusable components typically requires more thought and effort than building a component meant to be used solely at the project level. However, your governance team may be the only group within your company that has a holistic view of all the projects and what is being built. Recognizing reusability could save your company significant money, while delivering functionality to the business more quickly.

However, implementing reusability within your company may not be as straightforward as many would hope. Once a component becomes reusable, it usually means that more than one project makes use of the component. This simple action typically makes way for the inevitable question: “Who will maintain the component on an ongoing basis?”

Initially, your company may be able to support reusable components at the project level, depending on the workload of the project-allocated developers and the impact of issues and enhancements from other projects using the component.

If your company has identified a number of reusable components, it may be time to consider a centralized development team that has the sole task of maintaining and enhancing, and potentially delivering, new components in the future to all other projects. This configuration does, however, come at additional cost.

It is good practice for your governance team to keep in mind that what your project team is developing may one day be reused somewhere else. This helps elevate the quality and avoids those “good enough” scenarios. That is not to say that your governance team should go to extremes to make sure everything developed within your company could be reused, but it should at least make some effort to keep that possibility alive.

Code standards should be in place and adhered to. This is especially true for Apex, where you are aiming for all code to at least follow the same standards in naming convention and code layout. This will provide for a more easily maintainable code base, in that all developers will be able to read the code that other developers have written without getting frustrated that every class they look at is different. Your coding standards should extend to comments and any header-type documentation that should be present at the top of every class’s source code. Providing useful information about the changes that have occurred to a specific Apex class via the use of the header and a brief change list could save other developers a lot of time trying to understand what has happened to the code and why.

Tip

Creating a simple header for each Apex class is a great way to introduce developers to what the class is going to support. Additionally, using a basic change list within this header that details the name of the developer, the date, and a brief description of the reason for the change can help dramatically when dealing with source control systems and merging code into other branches. The change list can give a developer an instant view of whether they are merging in the right direction. Additionally, the comments within your Apex code do not contribute to the consumption of your Apex allowance, so why not?

Salesforce has implemented a few solutions to assist developers in creating reusable components in Visualforce. Some are more flexible than others and are as shown in Table 7-4.
Table 7-4

Reusability Solutions

Solution

Description

Define custom components

This is an approach that is similar to encapsulating Apex code in methods that can be reused by many programs. By encapsulating a common design pattern in a custom component, it can be reused by one or more Visualforce pages.

Define templates with <apex:composition>

This approach allows your projects to define a base template that will allow for portions of that template to change when implemented. This approach should be used when you want to maintain an overall structure on a page, but need the content of individual pages to be different.

Referencing an existing page with <apex:include>

This approach allows the entire contents of a Visualforce page to be inserted into another page. This approach should be used when your project team wants to replicate the same content in multiple areas.

Your governance team should make sure that your project team has used the correct solution given what the project is trying to achieve. Make sure that any custom components are not used to define reusable Visualforce pages. Your project should use one of the two templating methods to reuse the content of an entire Visualforce page.

If your project team is looking to store configuration settings that control the behavior of the application it is building, your governance team may need to review the approach the project team has taken. If your project team is creating a packaged solution, then there are features that can be used on the Salesforce platform to accomplish managing application configuration, but they may not be completely appropriate for certain situations, as shown in Table 7-5.
Table 7-5

Managing Application Configuration

Solution

Description

Custom objects

This approach might be one of the easiest to implement, but custom objects should be focused on business outcomes rather than application configuration. It is unlikely that your project will be creating numerous records for configuration; therefore, this solution would not be appropriate. Additionally, for packages, your project will be unable to distribute the configuration data without additional scripts to populate the data in the customer objects.

Custom Settings (List)

This approach provides the same settings for every user, which may not be the desired functionality. Custom settings are similar to custom objects but do not require the developer to query the object; the data is accessible directly.

Custom Settings (Hierarchy)

This approach is similar to custom settings (list); however, the settings can be different from user to user. From a developer perspective this is a useful solution for holding configuration settings. These settings are not packageable, so an alternative approach to creating a default set of configuration settings will be required (such as an install script).

Custom Metadata

This approach is probably the best option. Your project can package the values, and end users can deploy them. However, there are specific Apex functions to access the metadata, such as Metadata.DeployContainer, which are asynchronous. Your project should develop a customer user interface for the end user to simplify the management of your application’s configuration.

Ultimately, your governance team is looking to be assured that the project has used the appropriate solution to meet the business requirements, taking into account maintainability and best practices on the Salesforce platform. Additionally, it may be that your governance team needs to take into account an element of pragmatism to assist the project team in meeting project timelines. Taking a dispensation approach for any areas where a project has strayed from best practices may be a good approach, allowing the project to meet project timelines and refactor any areas where corners may have been cut to meet a deadline.

Method

This is the formal method for Phase F of the Salesforce Platform Governance Method. The objectives of Phase F are to ensure that your project teams have used the Salesforce platform’s programmatic capabilities, adhering to best practices to ensure the application being developed can be maintained and operational on the Salesforce platform unhindered in the future. The areas that will be assessed during this phase are as follows:
  • Design and Functionality

  • Performance and Scalability

  • Maintainability and Reuse

Approach

It is not unusual for Apex, Lightning components, and Visualforce pages to be numerous and lengthy. It may be possible for your governance team to manually check the source code delivered by your projects, but it is likely not very practical. Therefore, an automated static code analysis solution (such as PMD) should be considered. This will take time to configure and set up within your organization, but the advantages for your development teams will be huge. These types of governance checks can be executed early within your application development lifecycle, which means your developers will get feedback early in their development process. This will allow your project teams to correct any deviation from standards in the code before it becomes expensive and impacts the timeline.

Ideally, given the timeline, your organization could integrate the code quality governance processes within the continuous delivery and continuous integration pipelines. However, if this is not something your organization can accommodate initially, then it should be possible for your developers to manually code check using tools such as PMD.

As always, your governance team is not a blocker to progress, but rather helps the business get the most out of the Salesforce platform, which does not support any form of application containerization. Therefore, your governance team is trying to ensure that multiple projects co-exist on the Salesforce platform in harmony, while additionally helping your project team deliver a quality solution that will serve your business for the future.

Inputs

For the governance process to be a success, the project team must have a few artifacts available for the governance team to review. Suggested artifacts to review for Phase E of the Salesforce Platform Governance Method are as follows:
  • Application configuration and source (or the repository in the instance of using a source control system) where appropriate

  • Development standards and best practices

Steps

Properly following the steps to govern your projects’ Apex, Visualforce, and Lightning components will help the project team deliver a quality solution that can confidently support your business for the foreseeable future. Additionally, you must ensure that the application being developed will operate without problems throughout Salesforce’s frequent update process.

Your application will have to withstand three substantial platform releases each year. Ultimately, your business will want to have these updates applied without causing any issues with your applications.

Design and Functionality

  1. 1.

    Govern the continuum of UI options used against those available on the platform (buttons, mashups, Canvas, Visualforce pages, and Lightning components)

     
  2. 2.

    Govern the sharing and visibility model in the code solution

     
  3. 3.

    Govern the code against the security best practices to ensure all Visualforce and Apex code is developed per OWASP standards

     
  4. 4.

    Govern the object-oriented design principles and design patterns that were adhered to when developing the solution (Singleton, etc.)

     
  5. 5.

    Govern the appropriate use of the Model-View-Controller pattern

     
  6. 6.

    Govern any Apex controllers against the technical standards (extensions to standard controllers and custom controllers)

     
  7. 7.

    Govern the usage of custom settings and synchronous vs. asynchronous patterns, and all the available execution contexts (e.g., batch, trigger, callout, etc.)

     
  8. 8.

    Govern the usage of batch Apex and the flex queue

     
  9. 9.

    Govern the Apex / Visualforce solution against the governor limits

     
  10. 10.

    Govern the order of execution of transactions within the platform (specifically against pre-existing triggers)

     
  11. 11.

    Govern the quality of test coverage (required for production deployment; call-out testing is a special case)

     
  12. 12.

    Govern the approach to error/exception handling

     

Performance and Scalability

  1. 1.

    Govern performance and scalability best practices have been considered within Visualforce pages and Apex code (performance profiling, use of static resources)

     
  2. 2.

    Govern the Apex and Visualforce performance to include LDV scenarios (pagination, JavaScript remoting)

     
  3. 3.

    Govern the use of external Web technologies and complementary UI technologies

     

Maintainability and Reuse

  1. 1.

    Govern multi-language support and determine whether the appropriate solution has been used to support globalization

     
  2. 2.

    Govern the options and techniques used to make programmatic components maintainable and reusable on the platform (custom settings, skeleton templates, custom metadata types)

     

Outputs

Once all the steps have been assessed, the outputs to Phase F are as follows:
  • Not Applicable – This phase in the Salesforce Platform Governance Method is not applicable to the project.

  • Remediate – The governance team requests that the project team remediates its design to accommodate the issues raised during the governance review.

  • Pass – The governance team has found no issues or concerns with the project team’s proposal and therefore the project has passed this governance phase.

  • Review – The governance team has found the inputs cannot be objectively measured and therefore a subjective view has been made, which will lead to a discussion with the project team to reach consensus. Although undesirable, this could be a consequence of unclear standards/policies.

Scenario

For our scenario we are going to focus on two steps: one from the Design and Functionality section and the other from the Maintainability and Reuse section of Phase F. These steps are as follows:
  • Govern the usage of batch Apex and the flex queue

  • Govern the options and techniques used to make programmatic components maintainable and reusable on the platform (custom settings, skeleton templates, custom metadata types)

Back with our fictitious company Bright Sound Guitars Ltd., Hanna Snyder, the project architect, suggested during the application architecture (Phase A) governance session that her project would be implementing an integration between the Salesforce platform and the stock control system in use at Bright Sound Guitars.

During the integration (Phase E) governance session, Hanna’s developer, Caitlyn, mentioned that they intended to develop the integration between the Salesforce application and the stock control system using Apex. Caitlyn suggested that there would be three parts to this integration, as follows:
  • A batch process that is scheduled and retrieves all the stock from the stock control system each night, updating the Salesforce platform

  • An action that she wants to add into the Salesforce platform’s user interface so that a manual stock transfer can occur

  • A trigger that will update a specific item within the stock control system when its status is changed on the Salesforce platform

On reviewing the code, the governance team first highlights that the batch appears a little open ended. It is unclear as to the number of batches that could be created and how large the batches are.

The governance team recommends placing some protection around the batch code so that platform limits are not breached, proper error handling is implemented, and alerts are available to the operations team if the batch is unable to run correctly.

The governance team then moves onto the maintainability of the Apex code that Caitlyn and the team have developed. The governance team highlights a few issues that could use fixing, which they believe will help with the longer-term maintainability of the code.

First, the governance team likes the comment header that the development team has put together, as shown in Figure 7-5, but have a few recommendations.
Figure 7-5

Code header comment

They recommend enhancing the header comment to include a change log. This will help the development team quickly see what has changed during any merge conflicts, as shown in Figure 7-6. Additionally, they noticed that the developers may have cut and pasted the header into each file, and have inadvertently kept the same description for every file.
Figure 7-6

Code header comment updated

With the updated header, the project team should easily be able to identify the latest changes and avoid any conflicts during a branch merge.

Second, the governance team moves onto standards for the naming of variables, as shown in Figure 7-7.
Figure 7-7

Variable naming

The governance team mentions that the preferred naming convention for variables is to use camelCase. Although there are a few standards for naming variables, the governance team has asked all development teams to follow this standard, as shown in Figure 7-8. It is also a core rule for the Apex PMD rule set.
Figure 7-8

Variable naming updated

Although the naming of variables appears to be a trivial requirement, it helps differentiate a variable from a class, for example. Also, making sure every developer follows the same standards helps with maintainability because all developers will feel comfortable with the code they are looking at.

The governance team notices the use of Global for the class declaration, as shown in Figure 7-9.
Figure 7-9

Use of Global

The governance team raises this with Caitlyn, wondering why this class was declared as Global. The governance team understands that the schedulable class that Caitlyn’s team has put together is correct. Caitlyn spots that this Global designation is an error, perhaps carried over from another cut-and-paste mistake. The code is changed as shown in Figure 7-10.
Figure 7-10

Use of Global updated

The use of Global affects whether a class is accessible from any other code on the Salesforce platform. Although not a critical issue, if the project does decide to move to a packaged solution it may need to be changed. The project may as well make the class declarations correct for their purposes.

The governance team takes Caitlyn and Hanna through the rest of their comments. Caitlyn is pleased with the feedback, and once all the changes have been implemented, she feels that the code has improved in quality and readability. Caitlyn knows that any issues in production are going to have to be picked up by her and her team, so she appreciates anything that can avoid this situation.

Summary

Developing on the Salesforce platform is not unlike doing so on any other development platform. However, because the Salesforce platform is a multi-tenant architecture, controls have been put in place by Salesforce to protect each tenant from one another. This adds some complexity to project development.

Phase F tackles the governance of a project’s programmatic solutions, making sure standards have been followed and platform considerations have been made. Having completed this governance phase, you have checked that the project team has adhered to development standards, considered whether the platform capabilities they have used align with the original intent for these capabilities, and worked within the platform constraints that exist.

You have highlighted to your project team any areas of concern within the programmatic solutions they have created and are confident that the project will remediate your concerns.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.10.153