Apex, what it is and how it improves Salesforce.com

A little over a year ago, Salesforce.com announced the Apex development language. There has been tons written about Apex. My goal here is to present what I think are the most salient points about Apex, why it’s a big deal, and how it will make things better for my Salesforce.com users. I’m not a killer programmer or industry analyst, so this article will focus on my strengths and look at what new angles Apex will give me for solving my customers’ business problems.

What is it?

Apex is a language to write procedural code that runs on the Salesforce servers. It’s like writing stored procedures–you can access and manipulate data quickly–it’s on the server and it’s compiled.

This was a big move forward for Salesforce. Until Apex, procedural code had to be written in your language of choice and it used the web API for access to data. While this worked, accessing lots of data was very slow as all the database access had to traverse the Internet with the added overhead of SOAP encapsulation. Apex happens on the server, so there is no travel time for the data.

It’s magic, right?

Turns out it’s not magic. It’s really not all that innovative in what it does. Client server setups have had this kind of functionality for decades, it seems. But in the context of the multi-tennant architecture of Salesforce, it is really innovative. With Apex, you now can get the best parts of client server along with the best parts of on-demand. I can write my own code but not kill my server. Pretty cool.

Language details

The language itself is syntactically appealing to me. It’s very terse, and had a number of conventions that make sense in the context of Salesforce, but might not make sense elsewhere. For example, there is a data type for Salesforce record Ids. Another example is a simple for loop structure for looping through a database query result. In comparison to working with their AJAX toolkit, I’ve found Apex to be quick and light, with little wasted code.

Another big positive of the Apex language is the Eclipse IDE plugin. The plugin for the popular Java development environment connects you directly to your Apex code on the Salesforce servers, and makes running unit tests a breeze. The developers I’ve shown the Eclipse plugin to have been jealous of features like automatically identifying the percentage of you code covered by your tests and listing which lines of code aren’t being covered at all. It has made my entry into test-driven development pretty smooth.

How does Apex stack up against other analogous languages? I have no idea, and I’ll leave that to experts in that arena.

Invoking Apex

You can invoke Apex code in 2 ways: via triggers and through web-service calls. Triggers are code blocks that are run on changes to the data in your database. By using triggers you can run your arbitrary code every time a new Opportunity is inserted, for example. Having code run automatically based on data events is really powerful, and can do a lot for the user experience. You can easily automate User tasks that would have to be done by hand, making the application experience much nicer.

Exposing your code via a web service makes it callable from the Salesforce UI. Apex has no facility for creating UI (newly announced VisualForce takes care of that), so exposing it as a web service makes that available to S-Controls, which can have UI. The User can click a button and fire your Apex code, replacing the need for complex S-Controls, and getting all the benefits mentioned earlier.

So, Apex is faster than S-Controls, with simpler syntax. It can be called from buttons and data triggers. But what does that mean for user experience, which is the real test in a CRM application?

Application benefits of Apex

The first benefit I saw to Apex when it was announced was the ability to use triggers to eliminate steps the User had to take. Here’s a real-world example.

In the nonprofit world we care about households. We have donors and other supporters, and we often know other members of their family. If we send them separate thank you letters, or (even worse) appeals for money, they might be offended. In most cases, we want to send one mailing to each household, naming the members of the household in the letter.

In Salesforce, we model this as a simple custom object that can have multiple Contacts associated with it. Then, we can use this object when we want to send mailings. But to get Households in the system is a bit of a drag for the user. A User would have to create a Contact, then create a Household and relate them together. Households have addresses, but so do contacts, so the User would have to make address changes in two places. Lastly, if a new person was added to the Household, their name would have to be added to the name of the household, so that the letters mailed would identify all known members.

Before Apex, we tackled these problems with S-Controls. We created an S-Control for creating Contacts that would automatically create a Household after the Contact save. The address fields would be synced at this time, but we had no way of keeping these automatically in sync later. We also got the name of the Household right, but the User was responsible for managing the data in the future.

With Apex we’ve been able to improve this situation. I’ve created a couple triggers:

  • When a Contact is created without a Household, a new Household is automatically created, the address is saved to the Contact and the Household, and it is named correctly.
  • When a Contact is added to or removed from a Household, the Household is renamed and the name is pushed to every Contact in the Household
  • If a Household or a Contact address changes, the change flows through to everyone in the Household

What this means is that all Householding activities are now fully automated. The User never need care about Households, they will just be there to be used when needed. As you can imagine, this is a big win and pretty exciting.

The second benefit to Apex is the ability to denormalize data in interesting ways. We’ve created triggers that do rollup calculations on related data and save it up to the Contact or Account. Apex can do complex calculations across much related data, so it’s more flexible and powerful than Rollup Summary Fields. But why is this valuable?

In Salesforce when you want to analyze data you build reports. Generally these reports look at one set of data–Contacts or Opportunities or Campaign Memberships. But often the questions that creative users come up with take multiple sets of data into account, or look at multiple pieces of data in the same set. Some examples of questions you can’t currently ask Salesforce are:

  • Who gave at least two donations in the last 5 years?
  • Who gave a donation and attended 3 events?
  • Are we converting our Members to Event attendees, or the other way around?

Apex lets us put strategic pieces of data on the Contact record. Then when we do a Campaign membership report, we can look at this other data at the same time. These native reports can fuel dashboards that are a level of analytics we don’t have right now. And because they are native, we can use the reports to create prospect lists and funnel those directly into Campaigns.

A third area where Apex can help immensely is with integrations. The plumbing of integration is pretty straightforward, but what is complex is supporting all the weird business cases that Users might have. Let’s look at our Household example above. Many integrations with Salesforce create Contact records at some point in the flow. Event registration, online donation processing, even the Outlook integration has a Create Contact form. But with Householding, these integrations won’t work, or will create incomplete data. A Contact with no Household is a problem, so we can’t use these kinds of external integratons.

But if Apex triggers fire whenever a Contact is created and take care of the Householding with no intervention, all of the sudden all these integrations work fine. The integrators don’t need to know about Householding or any other crazy processes–they just create a Contact and leave it up to me to write the correct triggers. This is really exciting for people writing integrations, I can assure you. We’re going to be offloading some of our Plone integration code that supports weird use cases to Apex triggers. Very happily, I might add.

Apex can also make callouts to external web services, making just about anything possible. I haven’t played with this yet but can’t wait to do things like geocoding, address certification, and who knows what else.

Nothing’s perfect

While I’ve been very positive so far, there are some limitations to Apex as it’s currently released. First is that triggers don’t cover all actions that could happen in the data. There are a number of junction tables that don’t listen for events. The two biggest for me are Opportunity Contact Role and Campaign Member. These are tables that connect Contacts to Opportunities and Campaigns, respectively. Because there are no triggers on those tables. I could change the donor on a gift, but wouldn’t be able to update the giving total to that Contact record. I also can’t recalculate the events a person has attended when we mark them as having attended an event. I think these are pretty significant holes in the Apex infrastructure that hopefully will be fixed soon. With them unfixed, users can take actions that will make the data unreliable. We hope to minimize these cases, but there is only so much we can do.

One way around gaps like the two I listed above is to use triggers as best we can and then run a nightly batch to clean up any changes that slipped through. But Apex as it’s currently released doesn’t let us schedule the execution of blocks of code in a cron-like fashion. I think that functionality will come.

The third limitation has to do with one of Salesforce’s greatest strengths–it’s multi-tenant architecture. When Salesforce decided to let crazy people like me run code on their servers, they had to protect themselves and their other customers from my bad code. So, they built a bunch of controls to make sure I couldn’t hog resources. Part of this control system is a set of governors that limit the kinds of operations you can do. A trigger can only have 20 SOQL statements in it, for example. If a trigger is fired by a change to one record, only 100 other records can be updated. Arrays can only have up to 1000 members. The list goes on.

So, the Apex cron job that would crawl through 20,000 opportunities nightly wouldn’t work in the current governor regime. A decent portion of the utility of Apex will hinge on how quickly these governors are lifted. It’s a tough problem to solve, and one that has direct cost implications for them, so we’ll see if they budge in the next 6 months.

Conclusion and next steps

I’m very bullish about Apex. It fills a need that has been wanting for a while. And it appears to fill it very nicely. There are some limitations in the current release, but still the benefit to user experience, analytics and integration are enormous, and the language and tools are very nice. We’re undergoing a process to rewrite as much of our custom code base from S-Controls to Apex. Initial experiments have been highly successful, and I’ve been very impressed by everything I’ve seen. Add to that the ability to adequately test the code we’re writing for the first time and I am incredibly happy with the direction we’re going.

As we convert our codebase and add new functionality, I will report back on our status and share code snippets and do some screencasts of interesting developments. I can’t wait to really get going on the Apex path–I feel like it’s going to change the way we do Salesforce, taking our systems to a level we’ve only been dreaming about.

7 Responses to “Apex, what it is and how it improves Salesforce.com”

  1. Glenn Wilson Says:

    Steve;

    Great article that explains how APEX fits in the salesforce customization space.

    The one great thing about APEX Code (and Pages) is not just the code but the people at Salesforce building, designing and supporting it. I’m amazed at how much they listen to the dev community and how fast updates and improvements to the language come out.

    Cheers;
    GlennW

  2. Steve Says:

    Thanks Glenn!

    We’re a pretty small player in the Salesforce universe–16 out of their 900,000 users. They surely don’t have to listen to us for fear of losing our account: they donate it anyway! But I am amazed by how in-tune Salesforce.com is with what’s being said about their platform. Salesforce.com employees read this blog and countless others. And it’s not just one marketing guy reading them–it seems to be a pervasive attitude of keeping your ear to the ground, be it blogs or discussion groups.

    It’s something that other companies could learn from. It’s one of the reasons we love Salesforce.com and one of the key reasons they are so successful. Turns out the CRM company is really good at CRM…

  3. Seth Schneider Says:

    Steve,

    What resources did you use to learn APEX?

    Seth

  4. Steve Says:

    First, get a developer account. Then, take a look at the Apex language reference:

    http://www.salesforce.com/us/developer/docs/apexcode/salesforce_apex_language_reference.pdf

    And the Cookbook:

    http://wiki.apexdevnet.com/index.php/Members:Cookbook

    I’ve found them both helpful. There is also an Apex discussion board at salesforce.com/developer to find answers to specific questions.

  5. Chris Atwood Says:

    This is great, i’ve been pointing people to this “primer” on it.

  6. Scott Hemmeter Says:

    As usual, good work. Nice and thorough.

    I am also bullish on Apex, but there are some limitations on it now as it related to AppExchange developers.

    As a developer of AppExchange apps, I’d love the ability to write Apex code as part of an AppExchange app. However, this code is currently not distributable and, if it were, would only be distributable to UE Orgs. Certified AppExchange apps can support PE, EE and UE orgs via the API now. I am sure this limit will change, but it’s an issue now.

    Also, Apex Code is a “strongly typed” language. There is no ability to perform Apex actions using a Partner WSDL paradigm whereby the configuration and you dynamically generate SOQL. Using the regular API from an external server, this is possible. The API allows you to make describe calls to get config info so that you can determine schema design and also know a user’s field level security rules. You can then dynamically build a SOQL statement in a variable and use that to do your query. Not in Apex. I believe you need to type out your SOQL in the code.

    Once the distribution of code limitation goes away, I can see using Apex Code to perform specific actions for AppExchange apps. However, being able to fully rely on it for an AppExchange app is a ways away. In the short-term, Apex Code would be used for callouts from an external server using the API to perform specific tasks against the org.

  7. Steve Says:

    Yeah, Scott, we ran into the “enterprise WSDL” limitation the other day. A drag, hopefully will be modified soon.

    And from the perspective of a developer, it sure is a small install base to develop for–I’m sure they’ll get to the point where your Apex code can be run in any instance, as long as it’s certified.

    As always, we’ll all be keeping our eye on the ever-changing landscape of Salesforce…

Leave a Reply