• No results found

Programmatic Development Languages

I

n this chapter you’ll learn more about how to create and maintain applications on the Force.com platform. In doing so you’ll encounter Apex, Visualforce, Structured Object Query Language (SOQL) and Structured Object Search Language (SOSL), which together form the core languages that are used to create software on the platform. These will be explained within the context of the Model-View-Controller pattern; a prolific architectural pattern that calls for the separation of application logic, data and user interface in order to reap the benefits of easier collaboration and maintenance.

By the end of the chapter, not only will you be aware of what you need to develop applications using Force.com, but you will also have a feel for the best practices in each area.

MVC in the Cloud

We’ve addressed the topics of software development models and the tools that you’ll need as a Force.com developer. A natural next step is the exploration of the languages and technologies that you’ll use to take your projects from specification document to real-world application.

Model-view-controller (MVC) is a prevalent architectural design pattern in modern software development. In short it promotes the separation of an application’s logic, user-interface, and data storage from one another. This architecture has risen in popularity as this isolation of data (the model), user-interface (the view) and logic (the controller) allows each component to be developed, tested and maintained independently.

The Force.com platform’s development architecture fits conveniently within the MVC pattern allowing development teams to take advantage of the separation of responsibilities. If you consider figure 4 - 1 and imagine the following scenario:

You have created a Visualforce page (the view) with a text field and a “Save” button. The text field holds your last name, and this is persisted in a custom object (the model). When the page loads the field on the view requests the stored first name value from the custom object; this communication happens via the page controller.

You might want to update your last name in which case you’d change the text field value and click the “Save” button. This click would trigger an event handler in the controller, which would feed the information from the page to the custom object.

The model, the view and the controller clearly have separate domains of operation and this allows you to work on each component independently.

Since the Force.com platform alludes to this design pattern we will discuss each platform language and technology within the context of these roles.

Salesforce.com is a multitenant architecture as explained in chapter 1. In order to prevent any application from consuming more than their fair share of the platform resources they have introduced restrictions on measurable program operations. These restrictions fall under the names governors and limits and together they force the developer to create code that is efficient such that all “tenants” get an equal share of the resource pie. Developers don’t like Governor Limits very much as their development style is forced into certain practices used to remain within these limits. However these practices ensure a code base that is neat in architecture and quick in execution. Governor Limits are applied differently to each area of the development platform and will be discussed those contexts.

The Model

Within the Force.com platform data persistence is provided through what are termed Objects. These come in two broad flavors as shown in chapter 2.

Objects are an excellent way to abstract away the database and it’s corresponding fields as this allows developers to work with data in an object-oriented way i.e. instead of working with data rows, on the Force.com platform data is encapsulated in a class-like structure with the data fields accessible via member variables. If we peek into the controller domain briefly you’ll see, as show in listing 4 - 1, that objects can be

instantiated, and their member variables can be assigned values in much the same way as class variables.

Listing 4 - 1. Object Manipulation in an Apex Class

What do developers expect from the model? Usually you’d need several abilities to be exposed:

o Data Creation o Data Retrieval o Data Update o Data Deletion o Data Security

The first four features are sometimes referred to as create, retrieve, update and delete or CRUD. Data retrieval is the most complex of CRUD on the platform having two languages devoted to this sole purpose. The other operations are semantically quite similar, and vary only in syntax and result and therefore make a good starting point.

Data security is configured using a combination of features such as profiles, roles and field-level security. These topics are discussed in more detail in chapter 2.

Data Creation, Manipulation, Update and Deletion

With most types of databases you’ll encounter operations to insert1, update2 and delete3data. Force.com is similar in this regard, with listing 4 - 2 demonstrating how to insert, update and delete a data record.

Listing 4 - 2. Insert, Update and Delete a Record with Apex Code

Note the distinction between data manipulation and data update at the third and fourth lines. Line three is manipulating the value of the member field “firstname” and line four stores the changed value.

There’s an additional command available that can perform inserts or updates, and knows which action is appropriate in a given situation. This command is called upsert4 and its usage is demonstrated in listing 4 - 3.

Listing 4 - 3

Each of these commands is simple and extensively documented so there is little else we can add. Instead we’ll detail the more interesting topic of data retrieval.

Data Retrieval using SOQL and SOSL

Data retrieval from data stores usually requires a query language. Probably the most common is structured query language (SQL), which comes in many varieties, which are syntactically similar.

The Force.com platform uses two languages for data retrieval, each of which has specific use-cases; essentially SOSL is capable of performing text searches across objects and returning several object types in the results whereas SOQL allows complex querying of data returning a single object type.

Of the two you’ll find that structured object query language (SOQL), which has its roots in SQL5, is the one you’ll use more frequently. This is another topic that is covered by torrents of documentation, so we’d like to give you a guiding hand on where to start.

SOQL

Syntactically SOQL is more or less a subset of SQL6 with each individual statement structured as shown in listing 4 – 4.

Listing 4 - 4

Querying with SOQL

Looking at listing 4 – 5 you can see how this syntax can be applied with the Apex programming language, as well as how you can work with the results of a query7.

Listing 4 - 5

Note that queries will always return data as complete object records unless aggregate functions are used (more on these later). In the second query we’ve demonstrated how you might retrieve a single field value by dereferencing the name field.

The above example assumes that exactly one record will be returned by the query, and this is often a dangerous assumption to make. If the query were to return zero or greater than one result, your application would throw a runtime error. In some cases it would be better to feed the results of a query into a list of objects as shown in listing 4 – 6.

Listing 4 - 6

Here you see the Apex syntax for lists of objects but don’t panic, it will be revisited later in more detail. This query is not capable of creating runtime errors; if no records are found the list will be empty, and if more than zero are found they’ll be added to the list.

There is another way to deal with a query that returns zero results. At times it’s better to implement an Apex language feature called exception handling to avoid this type of runtime error; this feature will be examined in a later section.

Apex Variables in SOQL

Once you dive into SOQL programming with Apex you’ll often find the need to filter your queries using the value in an Apex variable. As an example consider the query in listing 4 – 6, but imagine that now, at development time, we don’t know what the last name might be as it’s determined by user input. In this case you’d use the syntax presented in listing 4 – 7.

Listing 4 - 7

Here we’ve declared the variable that will hold the last name value, and delimited said variable with a colon. Using a local variable within a SOQL statement is known as a bind, and they can be simple variables (as shown above) or formed by expressions8.

Object Relationships & SOQL

In modern development most databases are relational i.e. records in one table are related to records in other tables through an established relationship. The situation is similar with salesforce.com objects and we’ve seen in previous chapters the types of relationships that can exist. On any platform you’ll need a way to traverse these relationships and salesforce.com encapsulated this is a concise and powerful way.

From an object point of view you can either be related to a parent or a child object. The difference in the syntax for each situation is shown in listing 4 – 8.

Listing 4 - 8

Be careful when using the first type of SOQL query as it can be difficult to predict (and restrict) the number of data rows returned i.e. each account can have any number of child contacts. Later we’ll see that there are operational limits on things such as the number of data rows retrieved by a single query or within a transaction.

The syntax for each of these query types is quite different but simple nonetheless. Accessing the related objects for each type of relationship is also different as is shown in listing 4 – 9 with follows on from listing 4 - 8.

Listing 4 - 9

Through these Apex variables you would have access to the contents of either the children or parent of the object in question9. Be aware that the syntax when dealing with custom object relationships. Consider the example in which we have a parent object called Father__c related to a child object called Son__c. Listing 4 – 10 shows the equivalent of the above code for custom object relationships.

Listing 4 - 10

It’s important to point out that the nested SOQL statement within the first query interrogates Sons__r. This “object” name is the relationship name given when the link between the objects is first established. It can also be changed later by editing the relationship field. Figure 4 – 2 shows where this option is first presented.

Dynamic SOQL

Dynamic SOQL is a feature of the platform lets an application dynamically build a SOQL string at runtime10. This way the value of a query string can be determined by user-input as is essential with any data centric application.

The syntax for the query string is the same as that of SOQL but the query execution requires a system method call as shown in listing 4 – 11.

Listing 4 - 11

Another superb feature of dynamic SOQL is that the query results can be returned as concrete objects (as above) or they can be returned as the generic sObject data type akin to listing 4 – 12. Variables of this object type can hold any type of object value, be it standard or custom. This allows you to write applications that cleverly reuse code and deal with data polymorphically.

Listing 4 - 12

Using dynamic SOQL also requires extra care as it involves more coding and error checking, and potentially exposes your application to SOQL injection attacks11. All the same, it is a powerful tool when used correctly.

SOQL Governor Limits

SOQL Governor Limits12 are one of the most discussed topics in the developer forums and many of the questions are nearly identical. The primary issues concern hitting the limit imposed on:

1. The total number of SOQL queries issued

2. The total number of records returned across your SOQL queries

The first limit is typically hit when developers execute queries within some repeated structure such as a loop which will result in the following exception:

System.Exception: Too many SOQL queries

As it’s one of the most common limits that beginners encounter we’ll demonstrate an example of the issue in action, as well as the solution.

Listing 4 - 13 shows a SOQL for-loop that contains another related query.

Listing 4 - 13

Depending on the executing code’s entry point the Governor and Limit value that is applied will vary e.g. if the first code to execute is within an Apex class you can issue 100 queries within the lifetime of that invocation. If execution began in a trigger however you can only issue 20 queries.

This problematic pattern is to be avoided at all cost. Salesforce.com restricts the number of queries because database round trips are expensive and can quickly affect the performance of the multitenant environment. The idiom used to resolve this is show in list 3 - 15. Note that you’ll need to be familiar with the Set and Map collection types in order to understand and implement this pattern effectively.

Listing 4 - 14

Although the code is commented we’d like to point out that the crux of this idiom is that there are no SOQL queries contained in any loops.

The second limit is less likely to be caused by an efficiency flaw and is a natural consequence of a growing data set. One common solution to this problem is to fire asynchronous method calls to run over your data set in batches of 10,000 (The limit for the number of SOQL queries executed through Apex). Since these would run in their own transactional context, each batch would be subject to fresh limits.

The process of creating and managing these batches can be complex and error prone, and if your situations allows for it you should take a look at using Batch Apex. Batch Apex will be discussed in the section title “Controller”, but in brief this technology is implemented using a certain type of Apex class, and the limit on the number of records fetched in these classes is currently 50 million.

This covers the basics of data retrieval but you will certainly want to dive into more detail after just a few experiences with SOQL13. Important advanced concepts to get familiar with early on are aggregate functions14, working with very large queries15 and SOQL for loops16.

SOSL

Structured object search language (SOSL) is a language used to make very fast, broad-sweep searches through your objects’ fields. Many object fields are text-indexed for SOSL making this type of query faster than an equivalent search made using SOQL.

When might you use SOSL instead of SOQL? An example might be when building search functionality into a Force.com Site. You need to let users find data based on keyword searches, and the results could be from a number of objects. Building an equivalent SOQL “search engine”

would require a number of queries, as well as complex multi-level logical branches. It is also likely that SOSL will perform this type of search more quickly.

Listing 4 – 15 shows the syntax of an SOSL statement17. Listing 4 - 15

Be aware that SOSL cannot search these objects or field types:

Fields that are defined as not searchable. You can interrogate an object for this property by calling its describeSOjects() method and examining the value of the property named searchable.

Number, date and checkbox fields.

Textarea fields aren’t searched unless you specify ALL FIELDS for the search group.

Certain attachment records for some standard objects.

It’s important to know that you’ll use SOSL sparingly as its role is quite niche. However, when the time comes to build bespoke search functionality very few languages can compare with SOSL for simplicity and speed.

Searching with SOSL

SOSL search statements are human friendly as is apparent in listing 4 – 16.

Listing 4 - 16

The syntax is quite different from that of SOQL, and the search results are organised differently as well. Firstly the result is a list of lists of sObject types. The reasons here are:

You are potentially searching multiple objects, and therefore need a list to house each object type. In the above example you would thus have one list of Accounts, one list of Contacts, and a list that holds each of these lists.

A variable of the SObject type can hold any other object type, so it doesn’t matter which objects your are searching through the results will always “fit” into this structure.

Listing 4 - 17 shows how you might assign the search results to variables of the specified types.

Listing 4 - 17

When planning on using SOSL it’s important to note that18:

The lists of objects in the search results are in the same order as they appear in the query.

SOSL queries can only be issued from Apex code or anonymous blocks. They cannot be used in triggers.

Text searches for a single or no characters cannot be executed.

Unit tests for SOSL searches require initialization using Test.setFixedSearchResults(List<Id> testIds).

Searching with SOSL has its place and makes serving search functionality very simple and quick. Consider having to build a small application that searches all fields of the Telephone type within your Org. Listing 4 - 18 shows how easy this is with SOSL.

Listing 4 - 18

Knowing when to use SOSL as opposed to SOQL requires some thought initially, but with a little experience you’ll easily discern which tool to apply to specific situations.

Apex Variables in SOSL

Needing the use of dynamic bind-variables within SOSL statements is commonplace. You’ll find that the syntax requirement is similar to that of SOQL, with the only noticeable difference being their positioning with a statement19. Listing 4 - 19 is a contrived example showing the use of bind-variables in SOSL.

Listing 4 - 19

Object Relationships & SOSL

Currently there is no way to search a child and return the parent, or vice versa with SOSL. You would overcome this by searching through either child or parent objects and then discovering the counterpart through that object’s relationships and/or Id.

Dynamic SOSL

Again Dynamic SOSL operates in much the same way as Dynamic SOQL, and supports the same features as static SOSL as well as being constrained by the same rules20.

Dynamic search statements are executed using the search.query(sosl_string) method where sosl_string is a string variable whose value is a valid SOSL search-statement. Listing 4 - 20 shows such an example.

Listing 4 - 20

Of particular interest here are the backslashes in the search string. These are used to escape special characters within the string so that they can be included in the string definition. In the above example the single quotes are a required part of the SOSL syntax, but if they weren’t escaped, the second quotation mark would “close” the string and the third would “open” a new string; this would not compile as it violates Apex syntax rules.

Of particular interest here are the backslashes in the search string. These are used to escape special characters within the string so that they can be included in the string definition. In the above example the single quotes are a required part of the SOSL syntax, but if they weren’t escaped, the second quotation mark would “close” the string and the third would “open” a new string; this would not compile as it violates Apex syntax rules.

Related documents