Andy in the Cloud

From BBC Basic to Force.com and beyond…


18 Comments

Creating, Assigning and Checking Custom Permissions

I have been wanting to explore Custom Permissions for a little while now, since they are now GA in Winter’15 i thought its about time i got stuck in. Profiles, Permission Sets have until recently, been focusing on granting permissions to entities only known to the platform, such as objects, fields, Apex classes and Visualforce pages. In most cases these platform entities map to a specific feature in your application you want to provide permission to access.

However there are cases where this is not always that simple. For example consider a Visualforce page you that controls a given process in your application, it has three buttons on it Run, Clear History and Reset. You can control access to the page itself, but how do you control access to the three buttons? What you need is to be able to teach Permission Sets and Profiles about your application functionality, enter Custom Permissions!

CustomPermissions
CustomPermission

NOTE: That you can also define dependencies between your Custom Permissions, for example Clear History and Reset permissions might be dependent on a Manage Important Process  custom permission in your package.

Once these have been created, you can reference them in your packaged Permission Sets and since they are packaged themselves, they can also be referenced by admins managing your application in a subscriber org.

SetCustomPermissions

The next step is to make your code react to these custom permissions being assigned or not.

New Global Variable $Permission

You can use the $Permission from a Visualforce page or as SFDCWizard points out here from Validation Rules! Here is the Visualforce page example given by Salesforce in their documentation.

<apex:pageBlock rendered="{!$Permission.canSeeExecutiveData}">
   <!-- Executive Data Here -->
</apex:pageBlock>

Referencing Custom Permissions from Apex

IMPORTANT UPDATE: Since API 41 (Winter’18) there is now a native way to read Custom Permissions. The following may still be useful if you have requirements not met by the native method. FeatureManagement.checkPermission.

In the case of object and field level permissions, the Apex Describe API can be used to determine if an object or field is available and for what purpose, read or edit for example. This is not going help us here, as custom permissions are not related to any specific object or field. The solution is to leverage the Permission Set Object API to query the SetupEntityAccess and CustomPermission records for Permission Sets or Profiles that are assigned to the current user.

The following SOQL snippets are from the CustomPermissionsReader class i created to help with reading Custom Permissions in Apex (more on this later). As you can see you need to run two SOQL statements to get what you need. The first to get the Id’s the second to query if the user actually has been assigned a Permission Set with them in.


List<CustomPermission> customPermissions =
    [SELECT Id, DeveloperName
       FROM CustomPermission
       WHERE NamespacePrefix = :namespacePrefix];

List<SetupEntityAccess> setupEntities =
    [SELECT SetupEntityId
       FROM SetupEntityAccess
       WHERE SetupEntityId in :customPermissionNamesById.keySet() AND
             ParentId IN (SELECT PermissionSetId
                FROM PermissionSetAssignment
                WHERE AssigneeId = :UserInfo.getUserId())];

Now personally i don’t find this approach that appealing for general use, firstly the Permission Set object relationships are quite hard to get your head around and secondly we get charged by the platform to determine security through the SOQL governor. As a good member of the Salesforce community I of course turned my dislike into an Idea “Native Apex support for Custom Permissions” and posted it here to recommend Salesforce include a native class for reading these, similar to Custom Labels for example.

Introducing CustomPermissionReader

In the meantime I have set about creating an Apex class to help make querying and using Custom Permissions easier. Such a class might one day be replaced if my Idea becomes a reality or maybe its internal implementation just gets improved. One things for sure, i’d much rather use it for now than seed implicit SOQL’s throughout a code base!

Its pretty straight forward to use, construct it in one of two ways, depending if you want all non-namespaced Custom Permissions or if your developing a AppExchange package, give it any one of your packaged Custom Objects and it will ensure that it only ever reads the Custom Permissions associated with your package.

You can download the code and test for CustomPermissionsReader here.


// Default constructor scope is all Custom Permissions in the default namespace
CustomPermissionsReader cpr = new CustomPermissionsReader();
Boolean hasPermissionForReset = cpr.hasPermission('Reset');

// Alternative constructor scope is Custom Permissions that share the
//   same namespace as the custom object
CustomPermissionsReader cpr = new CustomPermissionsReader(MyPackagedObject.SObjectType);
Boolean hasPermissionForReset = cpr.hasPermission('Reset');

Like any use of SOQL we must think in a bulkified way, indeed its likely that for average to complex peaces of functionality you may want to check at least two or more custom permissions once you get started with them. As such its not really good practice to make single queries in each case.

For this reason the CustomPermissionsReader was written to load all applicable Custom Permissions and act as kind of cache. In the next example you’ll see how i’ve leveraged the Application class concept from the Apex Enterprise Patterns conventions to make it a singleton for the duration of the Apex execution context.

Here is an example of an Apex test that creates a PermissionSet, adds the Custom Permission and assigns it to the running user to confirm the Custom Permission was granted.

	@IsTest
	private static void testCustomPermissionAssigned() {

		// Create PermissionSet with Custom Permission and assign to test user
		PermissionSet ps = new PermissionSet();
		ps.Name = 'Test';
		ps.Label = 'Test';
		insert ps;
		SetupEntityAccess sea = new SetupEntityAccess();
		sea.ParentId = ps.Id;
		sea.SetupEntityId = [select Id from CustomPermission where DeveloperName = 'Reset'][0].Id;
		insert sea;
		PermissionSetAssignment psa = new PermissionSetAssignment();
		psa.AssigneeId = UserInfo.getUserId();
		psa.PermissionSetId = ps.Id;
		insert psa;

		// Create reader
		CustomPermissionsReader cpr = new CustomPermissionsReader();

		// Assert the CustomPermissionsReader confirms custom permission assigned
		System.assertEquals(true, cpr.hasPermission('Reset'));
	}

Seperation of Concerns and Custom Permissions

Those of you familiar with using Apex Enterprise Patterns might be wondering where checking Custom Permission fits in terms of separation of concerns and the layers the patterns promote.

The answer is at the very least in or below the Service Layer, enforcing any kind of security is the responsibility of the Service layer and callers of it are within their rights to assume it is checked. Especially if you have chosen to expose your Service layer as your application API.

This doesn’t mean however you cannot improve your user experience by using it from within Apex Controllers,  Visualforce pages or @RemoteAction methods to control the visibility of related UI components, no point in teasing the end user!

Integrating CustomerPermissionsReader into your Application class

The following code uses the Application class concept i introduced last year and at Dreamforce 2014, which is a single place to access your application scope concepts, such as factories for selectors, domain and service class implementations (it also has a big role to play when mocking).

public class Application {

	/**
	 * Expoeses typed representation of the Applications Custom Permissions
	 **/
	public static final PermissionsFactory Permissions = new PermissionsFactory();

	/**
	 * Class provides a typed representation of an Applications Custom Permissions
	 **/
	public class PermissionsFactory extends CustomPermissionsReader
	{
		public Boolean Reset { get { return hasPermission('Reset'); } }
	}
}

This approach ensures their is only one instance of the CustomPermissionsReader per Apex Execution context and also through the properties it exposes gives a compiler checked way of referencing the Custom Permissions, making it easier for application developers code to access them.

if(Application.Permissions.Reset)
{
  // Do something to do with Reset...
}

Finally, as a future possibility, this approach gives a nice injection point for mocking the status of Custom Permissions in your Apex Unit tests, rather than having to go through the trouble of setting up a Permission Set and assigning it in your test code every time as shown above.

Call to Action: Ideas to Upvote

While writing this blog I created one Idea and came across a two others, i’d like to call you the reader to action on! Please take a look and of course only if you agree its a good one, give it the benefit of your much needed up vote!

 


11 Comments

Mocking SOQL sub-select query results

If your a fan of TDD you’ll hopefully have been following FinancialForce.com‘s latest open source contribution to the Salesforce community, known as ApexMocks. Providing a fantastic framework for writing true unit tests in Apex. Allowing you to implement mock implementations of classes used by the code your testing.

The ability to construct data structures returned by mock methods is critical. If its a method performing a SOQL query, there has been an elusive challenge in the area of queries containing sub-selects. Take a look at the following test which inserts and then queries records from the database.

	@IsTest
	private static void testWithDb()
	{
		// Create records
		Account acct = new Account(
			Name = 'Master #1');
		insert acct;
		List<Contact> contacts = new List<Contact> {
			new Contact (
				FirstName = 'Child',
				LastName = '#1',
				AccountId = acct.Id),
			new Contact (
				FirstName = 'Child',
				LastName = '#2',
				AccountId = acct.Id) };
		insert contacts;

		// Query records
		List<Account> accounts =
			[select Id, Name,
				(select Id, FirstName, LastName, AccountId from Contacts) from Account];

		// Assert result set
		assertRecords(acct.Id, contacts[0].Id, contacts[1].Id, accounts);
	}

	private static void assertRecords(Id parentId, Id childId1, Id childId2, List<Account> masters)
	{
		System.assertEquals(Account.SObjectType, masters.getSObjectType());
		System.assertEquals(Account.SObjectType, masters[0].getSObjectType());
		System.assertEquals(1, masters.size());
		System.assertEquals(parentId, masters[0].Id);
		System.assertEquals('Master #1', masters[0].Name);
		System.assertEquals(2, masters[0].Contacts.size());
		System.assertEquals(childId1, masters[0].Contacts[0].Id);
		System.assertEquals(parentId, masters[0].Contacts[0].AccountId);
		System.assertEquals('Child', masters[0].Contacts[0].FirstName);
		System.assertEquals('#1', masters[0].Contacts[0].LastName);
		System.assertEquals(childId2, masters[0].Contacts[1].Id);
		System.assertEquals(parentId, masters[0].Contacts[1].AccountId);
		System.assertEquals('Child', masters[0].Contacts[1].FirstName);
		System.assertEquals('#2', masters[0].Contacts[1].LastName);
	}

Now you may think you can mock the results of this query by simply constructing the required records in memory, but you’d be wrong! The following code fails to compile with a ‘Field is not writeable: Contacts‘ error on line 16.

		// Create records in memory
		Account acct = new Account(
			Id = Mock.Id.generate(Account.SObjectType),
			Name = 'Master #1');
		List<Contact> contacts = new List<Contact> {
			new Contact (
				Id = Mock.Id.generate(Contact.SObjectType),
				FirstName = 'Child',
				LastName = '#1',
				AccountId = acct.Id),
			new Contact (
				Id = Mock.Id.generate(Contact.SObjectType),
				FirstName = 'Child',
				LastName = '#2',
				AccountId = acct.Id) };
		acct.Contacts = contacts;

While Salesforce have gradually opened up write access to previously read only fields, the most famous of which being Id, they have yet to enable the ability to set the value of a child relationship field. Paul Hardaker contacted me recently to ask if this problem had been resolved, as he had the very need described above. Using his ApexMock’s framework he wanted to mock the return value of a Selector class method that makes a SOQL query with a sub-select.

Driven by an early workaround (I believe Chris Peterson found) to the now historic inability to write to the Id field. I started to think about using the same approach to stich together parent and child records using the JSON serialiser and derserializer. Brace yourself though, because its not ideal, but it does work! And i’ve managed to wrap it in a helper method that can easily be adapted or swept out if a better solution presents itself.

	@IsTest
	private static void testWithoutDb()
	{
		// Create records in memory
		Account acct = new Account(
			Id = Mock.Id.generate(Account.SObjectType),
			Name = 'Master #1');
		List<Contact> contacts = new List<Contact> {
			new Contact (
				Id = Mock.Id.generate(Contact.SObjectType),
				FirstName = 'Child',
				LastName = '#1',
				AccountId = acct.Id),
			new Contact (
				Id = Mock.Id.generate(Contact.SObjectType),
				FirstName = 'Child',
				LastName = '#2',
				AccountId = acct.Id) };

		// Mock query records
		List<Account> accounts = (List<Account>)
			Mock.makeRelationship(
				List<Account>.class,
				new List<Account> { acct },
				Contact.AccountId,
				new List<List<Contact>> { contacts });			

		// Assert result set
		assertRecords(acct.Id, contacts[0].Id, contacts[1].Id, accounts);
	}

NOTE: Credit should also go to Paul Hardaker for the Mock.Id.generate method implementation.

The Mock class is provided with this blog as a Gist but i suspect will find its way into the ApexMocks at some point. The secret of this method is that it leverages the fact that we can in a supported way expect the platform to deserialise into memory the following JSON representation of the very database query result we want to mock.

[
    {
        "attributes": {
            "type": "Account",
            "url": "/services/data/v32.0/sobjects/Account/001G000001ipFLBIA2"
        },
        "Id": "001G000001ipFLBIA2",
        "Name": "Master #1",
        "Contacts": {
            "totalSize": 2,
            "done": true,
            "records": [
                {
                    "attributes": {
                        "type": "Contact",
                        "url": "/services/data/v32.0/sobjects/Contact/003G0000027O1UYIA0"
                    },
                    "Id": "003G0000027O1UYIA0",
                    "FirstName": "Child",
                    "LastName": "#1",
                    "AccountId": "001G000001ipFLBIA2"
                },
                {
                    "attributes": {
                        "type": "Contact",
                        "url": "/services/data/v32.0/sobjects/Contact/003G0000027O1UZIA0"
                    },
                    "Id": "003G0000027O1UZIA0",
                    "FirstName": "Child",
                    "LastName": "#2",
                    "AccountId": "001G000001ipFLBIA2"
                }
            ]
        }
    }
]

The Mock.makeRelationship method turns the parent and child lists into JSON and goes through some rather funky code i’m quite proud off, to splice the two together, before serialising it back into an SObject list and vola! It currently only supports a single sub-select, but can easily be extended to support more. Regardless if you use ApexMocks or not (though you really should try it), i hope this helps you write a few more unit tests than you’ve previous been able.

 


6 Comments

Preview of Advanced Apex Enterprise Patterns Session

At this years Dreamforce i will be presenting not one, but two sessions on Apex Enterprise Patterns this year. The first will be re-run of last years session, Apex Enterprise Patterns : Building Strong Foundations. The second will be a follow on session dealing with more advanced topics around the patterns. Imaginatively entitled Advanced Apex Enterprise Patterns. The current abstract for this session is as follows…

Complex code can easily get out of hand without good design, so in this deep dive you will better understand how to apply the advanced design patterns used by highly experienced Salesforce developers. Starting with Interface & Base Class examples of OO design we quickly move on to new design features including: Application Factory, Field Level Security Support, Selector FieldSet support and Dependency Injection, Mock Testing of Services, Domain and Selector layers.​ By the end you will have a better understanding of how and when to apply these advanced Apex patterns.

If you attended the FinancialForce.com DevTalk in June this year, you will have got a sneak peak of some of the improvements being made to the supporting library for the patterns available in this repo. If you didn’t you’ll have to wait till Dreamforce! Oh go on then, i’ll give you a teaser here…

  • Introduction
  • Selector Enhancements, FieldSet and QueryFactory Support
  • Application Factory Introduction
  • Using Apex Interfaces to implement Common Service Layer Functionality
  • Introducing ApexMocks
  • Using ApexMocks with Service, Selector and Domain Layers
  • Field Level Security Experiment
  • Q&A 

I’m quite excited about all this content, but perhaps if pushed, i’d have to highlight the new Application Factory concept along with the integration with the exciting new ApexMocks library (also from FinancialForce.com R&D). This brings with it easier support for implementing polymorphic use cases in your application and the ability to mock layers of the patterns, such as Unit Of Work, Domain, Selector and Service layers. Allowing to develop true unit tests that are fast to execute by the platform and plentiful in terms of the variation of tests you’ll be able to develop without fear of extending the time your sat waiting for tests to execute!

Its is against my nature to publish a blog without a code sample in it, so i’ll leave you to ponder the following….

	public void applyDiscounts(Set<ID> opportunityIds, Decimal discountPercentage)
	{
		// Create unit of work to capture work and commit it under one transaction
	    fflib_ISObjectUnitOfWork uow = Application.UnitOfWork.newInstance();

		// Query Opportunities
		List<Opportunity> oppRecords =
			OpportunitiesSelector.newInstance().selectByIdWithProducts(opportunityIds);

		// Apply discount via Opportunties domain class behaviour
		IOpportunities opps = Opportunities.newInstance(oppRecords);
		opps.applyDiscount(discountPercentage, uow);

		// Commit updates to opportunities
		uow.commitWork();
	}

Here is a more generic service layer example, leveraging polymorphic Domain classes!

	public void generate(Set<Id> sourceRecordIds)
	{
		// Create unit of work to capture work and commit it under one transaction
		fflib_ISObjectUnitOfWork uow = Application.UnitOfWork.newInstance();

		// Invoicing Factory helps domain classes produce invoices
		InvoicingService.InvoiceFactory invoiceFactory = new InvoicingService.InvoiceFactory(uow);

		// Construct domain class capabile of performing invoicing
		fflib_ISObjectDomain domain =
			Application.Domain.newInstance(
				Application.Selector.selectById(sourceRecordIds));
		if(domain instanceof InvoicingService.ISupportInvoicing)
		{
			// Ask the domain object to generate its invoices
			InvoicingService.ISupportInvoicing invoicing = (InvoicingService.ISupportInvoicing) domain;
			invoicing.generate(invoiceFactory);
			// Commit generated invoices to the database
			uow.commitWork();
			return;
		}

		// Related Domain object does not support the ability to generate invoices
		throw new fflib_Application.ApplicationException('Invalid source object for generating invoices.');
	}

This last example shows how ApexMocks has been integrated into Application Factory concept via the setMock methods. The following is true test of only the service layer logic, by mocking the unit of work, domain and selector layers.

	@IsTest
	private static void callingServiceShouldCallSelectorApplyDiscountInDomainAndCommit()
	{
		// Create mocks
		fflib_ApexMocks mocks = new fflib_ApexMocks();
		fflib_ISObjectUnitOfWork uowMock = new fflib_SObjectMocks.SObjectUnitOfWork(mocks);
		IOpportunities domainMock = new Mocks.Opportunities(mocks);
		IOpportunitiesSelector selectorMock = new Mocks.OpportunitiesSelector(mocks);

		// Given
		mocks.startStubbing();
		List<Opportunity> testOppsList = new List<Opportunity> {
			new Opportunity(
				Id = fflib_IDGenerator.generate(Opportunity.SObjectType),
				Name = 'Test Opportunity',
				StageName = 'Open',
				Amount = 1000,
				CloseDate = System.today()) };
		Set<Id> testOppsSet = new Map<Id, Opportunity>(testOppsList).keySet();
		mocks.when(domainMock.sObjectType()).thenReturn(Opportunity.SObjectType);
		mocks.when(selectorMock.sObjectType()).thenReturn(Opportunity.SObjectType);
		mocks.when(selectorMock.selectByIdWithProducts(testOppsSet)).thenReturn(testOppsList);
		mocks.stopStubbing();
		Decimal discountPercent = 10;
		Application.UnitOfWork.setMock(uowMock);
		Application.Domain.setMock(domainMock);
		Application.Selector.setMock(selectorMock);

		// When
		OpportunitiesService.applyDiscounts(testOppsSet, discountPercent);

		// Then
		((IOpportunitiesSelector)
			mocks.verify(selectorMock)).selectByIdWithProducts(testOppsSet);
		((IOpportunities)
			mocks.verify(domainMock)).applyDiscount(discountPercent, uowMock);
		((fflib_ISObjectUnitOfWork)
			mocks.verify(uowMock, 1)).commitWork();
	}

All these examples will be available in the sample application repo once i’ve completed the prep for the session in a few weeks time.

Sadly the FinancialForce.com session on ApexMocks was not selected for Dreamforce 2014, however not to worry! FinancialForce.com will be hosting a DevTalk event during Dreamforce week where Jesse Altman will be standing in for the library author Paul Hardaker (get well soon Paul!), book your place now!

Finally, if you have been using the patterns for a while and have a question you want to ask in this session, please feel free to drop your idea into the comments box below this blog post!


29 Comments

Spring’14 Visualforce Remote Objects Introduction

Salesforce have provided further support for JavaScript in the upcoming Spring’14 release. With a new flavour of the popular Visualforce Remoting facility. Visualforce Remote Objects is a pilot feature I have been trying out in a pre-release org. It’s aim is effectively to make performing database operations, like create, read, update and delete in JavaScript as easy as possible without the need for Apex, and without consuming the orgs daily API limits. This blog introduces the feature and contrasts it with its very much still relevant Visualforce Remoting brother.

Consider a master detail relationship between WorkOrder__c and WorkOrderLineItem__c. The first thing you need to do is declare your intent to access these objects via JavaScript on your Visualforce page with some new tags.

	<apex:remoteObjects >
	    <apex:remoteObjectModel name="WorkOrder__c" fields="Id,Name,AccountName__c,Cost__c"/>
	    <apex:remoteObjectModel name="WorkOrderLineItem__c" fields="Id,Name,Description__c,Hours__c,WorkOrder__c"/>
	</apex:remoteObjects>

The following JavaScript can now be used to access the JavaScript objects the above automatically injects into the page (note that while not shown there is further control over object and field naming, i used the defaults here).

It is an async API, so you provide a function call back to handle the result of the operations (create, update, delete and select are supported), it does not throw exceptions. In the example below if the insert of the Work Order master record is successful the child is then inserted. Note the event parameter actually contains the Id of the inserted record.

		function doSomethingJS(answer)
		{
			// Create work order
			var workOrder = new SObjectModel.WorkOrder__c();
			workOrder.set('AccountName__c','Hitchhikers.com');
			workOrder.set('Cost__c', answer * 100);
			workOrder.create(function(error, result, event)
				{
					// Success?
					if(error == null)
					{
						// Create work order line item
						var workOrderLineItem = new SObjectModel.WorkOrderLineItem__c();
						workOrderLineItem.set('Description__c', 'Answering the question');
						workOrderLineItem.set('Hours__c', answer);
						workOrderLineItem.set('WorkOrder__c', result[0]);
						workOrderLineItem.create(function(error, result, event)
							{
								// Errors?
								if(error!=null)
									alert(error);
								else
									alert('Success');
							} );
						return;
					}
					// Display error
					alert(error);
				} );
		}

As per the documentation, this means you no longer need an Apex controller to do this. You can also query using this object model as well, as per this the pre-release documentation querying a Wharehouse object. However before we cast aside our Apex thoughts, lets look at what the above would like implemented via a Remote Action.

		function doSomethingApex(answer)
		{
			// Create work order and line item via Apex
			Visualforce.remoting.Manager.invokeAction(
				'{!$RemoteAction.RemoteObjectDemoController.doSomething}',
				answer,
				function(result, event){
					alert(event.status ? 'Success' : event.message);
				});
		}

The following Apex code implements the remote action.

	@RemoteAction
	public static void doSomething(Integer answer)
	{
		WorkOrder__c workOrder = new WorkOrder__c();
		workOrder.AccountName__c = 'Hitchhikers.com';
		workOrder.Cost__c = answer * 100;
		insert workOrder;
		WorkOrderLineItem__c workOrderLineItem = new WorkOrderLineItem__c();
		workOrderLineItem.Description__c = 'Answering the question';
		workOrderLineItem.Hours__c = answer;
		workOrderLineItem.WorkOrder__c = workOrder.Id;
		insert workOrderLineItem;
	}

On the face of it, it may appear both accomplish the same thing, but there is a very important and critical architecture difference between them. To help illustrate this i created a page to invoke both of these options. Screen Shot 2014-01-22 at 08.48.56

Screen Shot 2014-01-22 at 09.03.07While also creating a strategically placed  Validation Rule on the Work Order Line item, one which would fail the insert if anything other than 42 was entered in the UI.

So given the validation rule in place, lets perform a test.

  1. Ensure there are no Work Order records present
  2. Enter an invalid value, say 32, click the buttons, observe the expect error
  3. Correct the value to 42, click the button again and observe the outcome on the database.
  4. The expected result is one Work Order record with a single Work Order Line Item record.

Testing the ‘Do Something (Apex)’ Button

After going through the test above, the button initially gives the error as expected…

Screen Shot 2014-01-22 at 09.00.05

When the value is corrected and button pressed again, the result is this…

Screen Shot 2014-01-22 at 08.54.07

The test passed.

Testing the ‘Do Something (JavaScript)’ Button

Going through the tests again, this button initially gives the error as expected…

Screen Shot 2014-01-22 at 09.00.25

When the value is corrected and button pressed again, the result is this…

Screen Shot 2014-01-22 at 08.56.54
While Visualforce Remote Objects technically performed as I believe Salesforce intended, this functional tests expectation failed. Since we have two Work Order records, one with no Work Order Lines and one that is what we expected. So why did this additional rogue Work Order record get created, what did we do wrong?

The answer lies in the scope of the database transaction created…

  • In the Visualforce Remote @RemoteAction use case the platform automatically wraps a transaction around the whole of the Apex code and rolls back everything if an error occurs, you can read more about this here.
  • In the Visualforce Remote Objects use case the database transaction is only around the individual database operations not around the whole JavaScript function. Hence by the time the Work Order Line Item fails to insert the Work Order has already been committed to the database. The user then corrects their mistake and tries again, hence we end up with two Work Orders and not one as the user expected.

Since Apex transaction management is so transparent most of the time (by design), its likely that the same assumption might be made of Remote Objects, however as you can see its not a valid one. Those of you that know core thoughts on patterns will also be thinking something else at this point, that presents a potentially even more compelling reason to be watchful over what logic you implement this way…

Separation of Concerns

As you may have gathered by now if you’ve been reading my blog for the last year, my other passion is Apex Enterprise Patterns. A key foundation of this is Separation of Concerns or SOC for short. SOC sees us layer our code so that aspects such as business logic are located in the same place, easily accessible and reusable (not mention easily testable) from other existing and future parts of our applications, such as API’s, Batch Apex etc.

While the above example is not that complex it illustrates when code in your JavaScript layer might start to become business logic and if so something you should ideally (if not solely for the reason above) consider keeping in your Service Layer and accessing via JavaScript Remoting @RemoteAction.

Summary

Despite this new feature the use of Visualforce Remoting with @RemoteAction Apex should still very much factor in your decision making.  And nor despite the issue above should we necessarily let the lack of transaction management count against our use of Visualforce Remote Objects either.

For sure this will become the best and lightest way to perform rapid client side querying without impacting API limits, and I am sure the alias feature (see docs) will be welcome to those preferring more elegant AngularJS or other bindings. All very nice! Furthermore if you are developing client logic that is essentially doing simple record editing then by all means let your Apex Triggers (Domain Layer) do its job and enforce the validity of those records.

Just keep in mind when your starting to write more and more JavaScript code that is orchestrating the updating, inserting or deleting of a set of  related records, you really need to be sure be sure you and your testers understand the transaction scope differences between the two approaches described here or switch over to Apex and let the platform manage the transaction scope for you. Finally its worth keeping in mind if you don’t have a client side automated testing strategy your automatically adding manual testing overhead to your backlog.

The full source code for this blog can be found here.

UPDATE: Since publishing this blog, Salesforce documentation team have written up an excellent additional topic covering some best practices and outlining the transactional differences described above. Its really great to see this type of content appearing in the standard Salesforce developer documentation, thank you Salesforce!

Other Notes and Observations

Here are some final points of note, given this is still pilot hopefully of use to Salesforce as feedback.

  • It does buffer requests to the server like Visualforce Remoting, very cool!
  • It does not complain when you set the wrong field or get the name wrong, like SObject.put and SObject.get do, maybe to be expected, though since we gave it the field list might have been nice?
  • It differs slightly from Dynamic Apex, it uses SObject.put, here WorkOrder__c.set is used
  • Success is expressed in ‘error’ being null, not quite what i expected, and different from Visualforce Remoting.
  • It does not implement field defaulting
  • Errors need to be hanlded by callbacks (as per VF Remoting), though by default errors are not emitted to the JavaScript console like Visualforce Remoting
  • References to fields on via the apex:remoteObjectModel fields attribute do not seem to surface as dependencies on the fields, which would be good given how soft references within the JavaScript are.


7 Comments

Ideas for Apex Enterprise Patterns Dreamforce 2013 Session!

ideaguy

Update: Dreamforce is over for another year! Thanks to everyone who supported me and came along to the session. Salesforce have now uploaded a recording of the session here and can find the slides here.

As part of this years Dreamforce 2013 event I will be once again running a session on Apex Enterprise Patterns, following up on my recent series of developer.force.com articles. Here is the current abstract for the session, comments welcome!

Building Strong Foundations: Apex Enterprise Patterns “Any structure expected to stand the test of time and change, needs a strong foundation! Software is no exception, engineering your code to grow in a stable and effective way is critical to your ability to rapidly meet the growing demands of users, new features, technologies and platform features. You will take away architect level design patterns to use in your Apex code to keep it well factored, easier to maintain and obey platform best practices. Based on a Force.com interpreation of Martin Fowlers Enterprise Architecture Application patterns and the practice of Separation of Concerns.” (Draft)

I’ve recently started to populated a dedicated Github repository that contains only the working sample code (with the library code in separate repo). So that i can build out a real working sample application illustrating in practical way the patterns in action. It already covers a number of features and use cases such as…

  • Layering Apex logic by applying Separation of Concerns
  • Visualforce controllers and the Service Layer
  • Triggers, validation, defaulting and business logic encapsulation via Domain layer
  • Applying object orientated programming inheritance and interfaces via Domain layer
  • Managing DML and automatic relationship ‘stitching’ when inserting records via Unit Of Work pattern
  • Factoring, encapsulating and standardising SOQL query logic via Selector layer

The following are ideas I’ll be expanding on in the sample application in preparation for the session…

  • Batch Apex and Visualforce Remoting (aka JavaScript callers) and the Service Layer
  • Apex testing without SOQL and DML via the Domain Layer
  • Exposing a custom application API, such as REST API or Apex API via Service Layer
  • Reuse and testing SOQL query logic in Batch Apex context via Selector Layer
  • Rich client MVC frameworks such as AngularJS and Service Side SOC

What do you think and what else would you like to see and discuss in this session?

Feel free to comment on this blog below, tweet me, log it on Github or however else you can get in touch.


10 Comments

Apex Enterprise Patterns – Selector Layer

A major theme in this series on Apex Enterprise Patterns has been ensuring a good separation of concerns, making large complex enterprise level code bases more clear, self documenting, adaptable and robust to change, be that refactoring or functional evolution over time.

In the past articles in this series we have seen Service logic that orchestrates how functional sub-domains work together to form the key business processes your application provides. Domain logic breaks down the distinct behaviour of each custom object in your application by bring the power of Object Orientated Programming into your code.

This article introduces the Selector, a layer of code that encapsulates logic responsible for querying information from your custom objects and feeding it into your Domain and Service layer code as well as Batch Apex jobs.

Selectors

You can read the rest of this article on the wiki.developerforce.com here, enjoy!

Series Summary

This completes the current series of articles on Apex Enterprise Patterns. The main goal was to express a need for Separation of Concerns to help make your Apex logic on the platform live longer and maintain its stability. In presenting three of the main patterns I feel help deliver this. If nothing else, I’d like to think you have started to think more about SOC, even if it’s just class naming. Though hopefully beyond that if you use some of the articles’ various base classes great, please feel free to contribute to them. If you don’t, or decide to skip some or use a different pattern implementation that’s also fine, thats what patterns are all about. If you do, I’d love to hear about other implementations.

Martin Fowler’s excellent patterns continue to be referenced on platforms, new and old. I’ve very much enjoyed adapting them to this platform and using them to effect better adoption of Force.com platform best practices along the way. Thanks to everyone for all the great feedback, long may your code live!


38 Comments

How To: Call Apex code from a Custom Button

Screen Shot 2013-07-16 at 08.21.48‘How do I call Apex code from a Custom Button?’ is a simple question, however the answer is covered across various developers guides and general documentation…

Having answered a number of questions on StackExchange over the year or so I’ve been active on it, I thought I’d compile this how to guide as reference peace. Of course its littered with links to the  excellent Salesforce documentation, so please do dig into those as well.

The steps are as follows to add either a Detail or a List View  button (as illustrated below) to Standard or Custom Object. It’s well worth going through the topics and general reference guides I’ve linked in more detail. I’ve given some examples of my own, but there are also plenty of them in the help topics I’ve linked to if you need more examples.

Screen Shot 2013-07-16 at 09.13.00Screen Shot 2013-07-16 at 09.12.46

Steps to Create a Custom Button that runs Apex Code

  1. Create a Apex Extension Controller class as shown in the examples below.
  2. Create a Visualforce page, using the ‘standardController‘ and ‘extensions‘ attributes on apex:page *
  3. Create a Custom Button using the Visualforce page as its Content Source
  4. Add the Custom Button to the appropriate Layout of the object
  5. Use either the ‘action‘ attribute (see warning below) or apex:commandButton‘s on your page to invoke Apex logic.


*
 You must also use the ‘recordSetVar‘ attribute on apex:page if you wish to create List View button.

Detail Page Custom Button Template

Example page and class using apex:commandButton to invoke the logic.

<apex:page standardController="Test__c" extensions="DetailButtonController">
    <apex:form >
        <apex:commandButton value="Do something" action="{!doSomething}"/>
    </apex:form>
</apex:page>

Apex controller code.

public with sharing class DetailButtonController
{
    private ApexPages.StandardController standardController;

    public DetailButtonController(ApexPages.StandardController standardController)
    {
        this.standardController = standardController;
    }

    public PageReference doSomething()
    {
        // Apex code for handling record from a Detail page goes here
        Id recordId = standardController.getId();
        Test__c record = (Test__c) standardController.getRecord();
        return null;
    }
}

Or to have your Apex logic run as soon as the user presses the Custom Button use the action attribute.

<apex:page standardController="Test__c" extensions="DetailButtonController"
           action="{!doSomething}">

To add the Custom Button should look something like this…

Screen Shot 2013-07-16 at 07.43.22

List View Custom Button Template

Example page and class, using apex:commandButton to invoke the logic.

<apex:page standardController="Test__c" extensions="ListButtonController"
           recordSetVar="TestRecords">
    <apex:form >
        <apex:commandButton value="Do something" action="{!doSomething}"/>
    </apex:form>
</apex:page>

Apex controller code.

public with sharing class ListButtonController
{
    private ApexPages.StandardSetController standardSetController;

    public ListButtonController(ApexPages.StandardSetController standardSetController)
    {
        this.standardSetController = standardSetController;
    }

    public PageReference doSomething()
    {
        // Apex code for handling records from a List View goes here
        List<Test__c> listViewRecords =
            (List<Test__c>) standardSetController.getRecords();
        List<Test__c> selectedListViewRecords =
            (List<Test__c>) standardSetController.getSelected();
        Boolean hasMore = standardSetController.getHasNext();
        return null;
    }
}

Or to have your Apex logic run as soon as the user presses the Custom Button use the action attribute.

<apex:page standardController="Test__c" extensions="ListButtonController"
           action="{!doSomething}" recordSetVar="TestRecords">

To add the Custom Button should look something like this…

Screen Shot 2013-07-16 at 07.43.58
WARNING: Use of ‘action’ attribute on apex:page and CSRF Attacks.

If you use the ‘action‘ attribute as per step 4 your Apex code will execute as soon as the Custom Button is pressed. However if your Apex code performs database updates this is considered unsecured as its possible that your code will be open to a CSRF attack. See this excellent topic from Salesforce for more information. If this is your case its better to use the apex:commandButton option and provide a confirmation button to your user before invoking your Apex code.

Since its Summer’13 release, Salesforce have started to add some support to allow us to use the ‘action’ attribute safely, which gives a better user experience since there is no need for a confirmation button. Currently however, the new ‘Require CSRF protection on GET requests‘ checkbox on the Visualforce page is only considered when the page is used to override the standard Delete button on an object. Hopefully support for Custom Button will arrive soon!

Update: 31st July 2013

Here is a great blog on sharing your Apex Controller class between Detail and List pages, Using one page and controller for both a “Detail Page Button” and a “List Button”.