I’m pleased to announce the immediate availability of the fourth edition of Advanced Apex Programming!
I know what you’re thinking – what has changed? Do I really need a new edition?
Well, the first thing you should know, is that this book is about 20% larger than the previous edition. But, the price is the same – instead of increasing the page count, I was able to increase the page size – from 6 x 9 to 7.5 x 9.25.
And what’s in that 20%?
Here’s a brief summary of the major changes for this edition:
Chapter 2: The section on “Controlling Program Flow” has been largely rewritten with a new example.
Chapter 3: The sections on “CPU Time Limits”, “Benchmarking”, “24-hour Limits” and “Other Platform Limits” are new or have been rewritten.
Chapter 5: There’s a new discussion on detecting duplicate fields in dynamic SOQL queries.
Chapter 6: The trigger framework has been enhanced, with particular attention to handling record DML updates across multiple trigger handlers (a subject discussed in previous editions but not actually demonstrated).
Chapter 7: New coverage of platform events.
Chapter 9 is a completely new topic: Application configuration. The previous chapters 9-12 are now chapter 10-13 and the following paragraphs refer to them by their new chapter number.
Chapter 10: Additional discussion of platform events.
Chapter 11: Revised recommendations for unit tests and managed packages.
Chapter 13: Updated for Salesforce DX
So even if you don’t buy this new edition, please don’t read the previous one – the platform has changed, and many of the earlier recommendations no longer reflect best practices.
And by the way – the Kindle edition is still priced considerably lower than the print edition – so that offers an inexpensive way to check out what’s new without buying a new printed book, for those of you who are more cost sensitive (I do recommend the printed book in general though, as listings just don’t come through that well in the eBook editions).
As always, watch for corrections and updates here on advancedapex.com – as I’m quite sure Salesforce will continue to update the platform faster than I can revise the book 🙂
Hi Dan! Thanks a lot for your book, it’s a great source of knowledge for apex development. I have one question regarding Chapter 9 where you explain how to manage app configuration. In the ConfigController class you don’t actually use the AppCustomSetting wrapper for AppConfig__c. Instead you access them directly in the controller. Why? Earlier in the chapter you wrote that it’s better to access custom settings/metadata via wrappers.
My intent (which could have been more clear) was that “access” in this context meant – to read and use configuration data in the application overall. Doing so allows you to add intelligence to the configurability, to isolate the application from the underlying configuration objects, and in most cases to prevent outside code from modifying the configuration.
However, the purpose configuration controller pages is to modify the configuration – they ultimately have to modify and update the underlying object. So this code has (or should have) the intelligence to do any necessary validation. Because its job is to modify the object, there’s little benefit in providing isolation from the object. In fact, it simplifies matters – as the page can easily hold all changes in memory and write the underlying object at once – something harder to do when using a wrapper (that presumably exposes each item as an individual property).
Now, one could make the argument that it makes sense to put the “write configuration” capability in the wrapper – say, in a scenario where you also provided an external API to modify configuration. But even there I’d lean to keeping it out of the main wrapper and instead creating a configuration writing class to be used both by the API and the controller. Ultimately part of the intent is to tightly control how outside code can modify configuration to ensure it remains valid and provide later flexibility for change.
When can we expect the new edition ?
I always watch for changes to Apex that enable or change design patterns. Those are what drive updates. Right now, I’m watching for the GA date on Queueable finalizers as the Apex technology that will drive a revision. So I’m thinking sometime in mid-late 2021 seems most likely.
I’m a bit confuse about how to go about viewing the sample code in the book. I downloaded the SFDX git repository but I’m not sure how to go about setting things up. I created a scratch org and pushed the repository but I’m not seeing anything. Could you help me with this?
Charles T. Green
The easiest way to set things up is to use the SourceTree application (https://www.sourcetreeapp.com/) and point it to your local repository. You’ll then see branches for each chapter. You can check out each chapter’s code – and push that code into your scratch org. There are many introductions to git (including a trail: https://trailhead.salesforce.com/en/content/learn/modules/git-and-git-hub-basics). I like sourcetree because it is graphical and easy to use.
I realize that using the code does requires a minimal working knowledge of git – but that working knowledge is, I believe, essential knowledge for every advanced developer in the age of SFDX.
Hey Dan, I very much appreciate your book and have recently been implementing from Chapter 7 ‘Going Asynchronous’ and more specifically ‘Going Asynchronous with Queueable Apex on page 186 and I ran into two issues and one of them I was hoping you could help direct me on because nothing online has given answers, so either I am so far off in the weeds no one can understand me, or I am a pioneer trying to blaze the way :).
1) In your SourceTree repository, it creates the ‘parameters’ field as a 255 character text field, but in the queable batch, your framework groups the IDs (18char) into batches of 100 with commas separating them, which requires a field size of 1900 to ensure no errors on size. I changed the field type to be a long text area and this fixed it but might consider updating the meta data in the project to have that field accept a longer value.
2) Here is my real issue which I outlined here: https://developer.salesforce.com/forums/?id=9062I000000IPfwQAG. I adapted your queueable APEX to work on the contacts object that makes an API callout and then updates the contact record. It works great until I enable duplicate rules for the contact object. This is where I see the odd behavior, the contacts insert except for the single contact that is out of compliance with the standard duplicate rules, my code fires correctly and creates the AsyncRequest__c record with the IDs of the contacts, but it never gets committed to the database. I have 0 errors that show up anywhere, my insert debugs show successful inserts but ultimately my code creating the AsyncRequests__c gets rolled back, but the contacts are successfully inserted. My question for you is two fold, 1) How do I catch that error that the commit was unsuccessful? and 2) How can the framework you outlined be modified to handle the standard duplicate rules? All the answers I have received are related to not using the standard duplicate rules but given how powerful they are, I’d like to find a way for both to co-exist. Thanks in advance!
You’ve run into an uncommon situation in the order of flow that occurs when the platform reprocesses existing records after reverting the database on a partial success. The trick here is to detect that condition and clear the alreadyprocessed flag. I’m still in the process of figuring out the best way to handle this, but I think the trick is to detect an increase in available limits, because limits also reset when this condition comes up. In other words – at your trigger entry point, you record certain limits (SOQL? CPU time? Not sure which will be most reliable). Normally, you would expect these to always increase between trigger calls. If you ever see a decrease, that would be a sign that the platform has reverted to a previous state, and you should reset the alreadyprocessed flag. Again I stress, I’ve only done preliminary research on this – but I’m pretty sure it’s the right approach. I hope that helps.
Regarding #1 – I’ve made a note of that for the next edition and the update list on the website (yes, I’m a bit behind on that – but these days being a bit behind is part of the new normal).