# Friday, 28 May 2010
A true REST interface with full support for HTTP Verbs, status codes, and URIs is currently not available on the Salesforce.com platform. However, a simple REST-like interface for getting objects can be developed using Salesforce Sites, Visualforce, and Apex.

This example uses a free Developer Edition with a Site named 'api' that uses only 2 Visualforce pages named 'rest' and 'error'. The rest page accepts a single parameter named 'soql', executes the SOQL query, and returns a JSON formatted response.

The error page is also used to generically handle all 40x and 50x errors.

The body of the error page returns a simple JSON message that the api is unavailable.
<apex:page contenttype="application/x-JavaScript; charset=utf-8" 
showheader="false" standardstylesheets="false" sidebar="false">
{"status": 500, "error": "api currently not available"}

The rest Visualforce page (full source at bottom of this post) accepts a SOQL parameter and returns JSON results. To get a list of all Leads with their First and Last names, you'd use the SOQL

select Id, FirstName, LastName from Lead
and pass this query to the REST interface in a GET format such as (example here)

Note that the rest page is defined as the default handler for the site named 'api', so it's not required in the URL.
This simple interface supports any flavor of SOQL, including the WHERE and LIMIT keywords, so you can pass queries like

select Id, FirstName, LastName from Lead where LastName='Smith' limit 20
REST interfaces often assume the unique ID of an object is the last portion of the URL request. This can similarly be achieved with a query like (example here)
select Id, FirstName, LastName from Lead where Id='00QA00000019xkpMAA' limit 1

All of these example queries will only return the Id field by default. To fix this, update the Sites Public Access Settings and grant Read access to the Lead object.

The new URL rewriting feature in Summer 10 provides some additional options the necessary means to implementing a RESTful interface with full support for object URIs and linking.

Visualforce Source Code for rest.page
<apex:page controller="RESTController" action="{!processRequest}" 
contentType="application/x-JavaScript; charset=utf-8" showHeader="false" 
standardStylesheets="false" sidebar="false">
Apex Source Code for RESTController.cls
public with sharing class RESTController {
	public void processRequest(){
    	if( HasError )
    	//Add support for other types of verbs here
    static final string ERROR_MISSING_SOQL_PARAM = 'Bad Request. Missing soql parameter';
    static final string ERROR_SOBJECT_MISSING	 = 'Bad Request. Could not parse SObject name from SOQL';
    static final string ERROR_FROM_MISSING		 = 'Bad request. SOQL missing FROM keyword';
    public void validateRequest(){
    	if(Query == null){
    		errorResponse(400, ERROR_MISSING_SOQL_PARAM);
    	else if(sObjectName == null){
    		//Force a get of object name property.
    		//Detailed error response should already be logged by sObjectName parser
    public boolean HasError = False;
    private void errorResponse(integer errorCode, string errorMessage){
    	JSONResponse.putOpt('status', new JSONObject.value(errorCode));
    	JSONResponse.putOpt('error', new JSONObject.value(errorMessage));
    	HasError = True;
    public void processGetQuery(){
    	Map<String, Schema.SObjectField> fieldMap = Schema.getGlobalDescribe().get(SObjectName).getDescribe().fields.getMap();
    	List<JSONObject.value> objectValues = new List<JSONObject.value>();
    	List<sObject> resultList = Database.query(Query);
    	for(sObject obj : resultList){
    		JSONObject json = new JSONObject();
    		json.putOpt('id', new JSONObject.value( obj.Id ));
    		for(SObjectField field : fieldMap.values() ){
    				string f = field.getDescribe().getName();
    				string v = String.valueOf( obj.get(field) );
    				json.putOpt(f, new JSONObject.value( v ));
    			catch(Exception ex){
    				//Ignore. Field not included in query
			objectValues.add(new JSONObject.value(json));
    	JSONResponse.putOpt('status', new JSONObject.value(200));
    	JSONResponse.putOpt('records', new JSONObject.value(objectValues));
    private string m_query = null;
    public string Query{
    		if(m_query == null && ApexPages.currentPage().getParameters().get('soql') != null){
    			m_query = ApexPages.currentPage().getParameters().get('soql');
    		return m_query;

	static final string SOQL_FROM_TOKEN = 'from ';    
    private string m_sObject = null;
    public string sObjectName{
    		if(m_sObject == null && Query != null){
    			string soql = Query.toLowerCase();
    			integer sObjectStartToken = soql.indexOf(SOQL_FROM_TOKEN);
    			if(sObjectStartToken == -1){
    				errorResponse(400, ERROR_FROM_MISSING);
    				return null;
    			sObjectStartToken += SOQL_FROM_TOKEN.length(); 
    			integer sObjectEndToken = soql.indexOf(' ', sObjectStartToken);
    			if(sObjectEndToken == -1)
    				sObjectEndToken = soql.length();
    			m_sObject = Query.substring(sObjectStartToken, sObjectEndToken);
    			m_sObject = m_sObject.trim();
    			system.debug('m_sObject = ' + m_sObject);
    		return m_sObject;
    private JsonObject m_jsonResponse = null;
    public JSONObject JSONResponse{
    		if(m_jsonResponse == null)
    			m_jsonResponse = new JSONObject();
    		return m_jsonResponse;
		set{ m_jsonResponse = value;}
	public String getJSONResult() {
    	return JSONResponse.valueToString();
	public static testMethod void unitTests(){
		RESTController controller = new RESTController();
		system.assertEquals(True, controller.HasError);
		system.assertEquals(True, controller.JSONResponse.has('status'));
		system.assertEquals(400, controller.JSONResponse.getValue('status').num);
		system.assertEquals(True, controller.JSONResponse.has('error'));
		system.assertEquals(ERROR_MISSING_SOQL_PARAM, controller.JSONResponse.getValue('error').str);
		controller = new RESTController();
		ApexPages.currentPage().getParameters().put('soql', 'select Id fro Lead');
		system.assertEquals(True, controller.HasError);
		system.assertEquals(True, controller.JSONResponse.has('status'));
		system.assertEquals(400, controller.JSONResponse.getValue('status').num);
		system.assertEquals(ERROR_FROM_MISSING, controller.JSONResponse.getValue('error').str);
		controller = new RESTController();
		ApexPages.currentPage().getParameters().put('soql', 'select Id from Lead');
		system.assertEquals(False, controller.HasError);
		system.assertEquals('Lead', controller.sObjectName);
		Lead testLead = new Lead(FirstName = 'test', LastName = 'lead', Company='Bedrock', Email='fred@flintstone.com');
        insert testLead;
        controller = new RESTController();
		ApexPages.currentPage().getParameters().put('soql', 'select Id from Lead where email=\'fred@flintstone.com\'');
		system.assertEquals(False, controller.HasError);
		system.assertEquals('Lead', controller.sObjectName);
		system.assertEquals(True, controller.JSONResponse.has('records'));
Friday, 28 May 2010 12:34:08 (Pacific Daylight Time, UTC-07:00)
# Saturday, 22 May 2010
The Google I/O Developer Conference this past week (May 19-20) was a highly anticipated event for both Google web and mobile Developers alike.

With the exception of Chrome OS, all of the technologies and products on my watch list unveiled new and exciting features that re-affirmed my belief that Google is indeed one of the leading cloud platforms to be embraced by all cloud Developers.

The marriage between the Android mobile OS and Google services is simply outstanding. The new Web Store works seamlessly with mobile devices and actions taken on either the desktop or mobile are immediately reflected on the other device.

Google handed out 2 mobile phones to attendees, a Motorola Droid and a HTC EVO 4G, and I was amazed at the ease and speed of syncing both devices with my existing Google Premier Apps account.

The dilemma I faced was whether to write mobile apps natively for Android apps or use HTML5. Geolocation, games, and apps requiring haptic response will most definitely be better served running natively on Android. General web sites and marketing centric apps written in HTML5 will enjoy the benefits of running cross platform (iPhone, Blackberry, Android) but will lack high end graphics and GPS support (although SVG and Geo Javascript extensions could address both of these in HTML5).

Developing for Google in previous years has been something of a hobby for many Developers, since there were few monetization opportunities outside AdWords and AdSense. Google unveiled several new monetization platforms for both desktop and mobile developers that will make Android very attractive to existing iPhone developers (plus Google doesn't discriminate apps uploaded to their Marketplace).

With 100K Android phone activations per day it's becoming very easy to do the quick math and trust that Google Android is a viable and profitable distribution vehicle.

A considerable amount of time was spent on Google Business during the day 1 keynote. The Google/VMWare partnership mirrored closely what was announced for VMForce just a couple weeks ago, although I think Salesforce did a much better job of helping Developers understand what was being offered via SpringSource. Google is serious about the business market and wants Java apps written on their platform.

I think the most underrated business feature is Google Apps Script. This is a free extension to Google Premier Apps that enables complex workflows between spreadsheets, web forms, email, and calendars. I would highly advise SMBs to use Apps Script for their business needs while larger Enterprises would probably benefit more from the SpringSource business platform.

All demonstration hiccups aside, the Google TV announcement was interesting from a consumer perspective. It was quite amazing to see Google's CEO on stage with the other CEO's associated with the launch (Sony, Best Buy, Intel, Logitech, and Adobe). That was some serious firepower and, if anything, really reaffirmed that Google is pursuing a stratified and open platform in contrast to Apple's closed platform.

On a technical note, I enjoyed spending some time with the Chrome development team during their open "Office Hours". The conversation with them inspired me to download the V8 Javascript engine and brush up on my C++ skills in order to contribute some JSON parsing enhancements I requested.

Most of what I was hoping for in HTML5 support was either previewed at the conference or is scheduled for delivery this year. The V8 engine is in the Android 2.2 Froyo release and we can expect 2010 to be a milestone year for evolving browser technology.

The unedited YouTube video below is a 10 minute walkthrough of the conference floor with both Hardware and Software vendors showing their wares (check out the Salesforce booth around minute 3).

Saturday, 22 May 2010 17:02:22 (Pacific Daylight Time, UTC-07:00)
# Monday, 17 May 2010

I'm getting on a plane tomorrow morning for San Francisco to attend the Google I/O conference. If you're a cloud developer and can only attend 1-2 conferences per year, then this conference should be on your calendar (in addition to Dreamforce).

Even though 90%+ of Google's revenue comes from search advertising, they are much more than a search engine these days. They've effectively leveraged their massively scalable Google File System to develop and host hundreds (if not thousands) of applications that are accessible throughout the world using nothing but a web browser.

Google has realized that the best way to increase revenue is not to push more customers towards Google, but to provide more accessibility to the web itself. You can deploy this somewhat altruistic strategy when you have a 72% market share.

Deploying highspeed fiber networks and launching the open source Android mobile operating system are just a couple examples of Google seeking to further enable access to the cloud on the premise that consumers of these networks/devices will eventually utilize the Google search engine and ads.

To see Android phone sales surpass iPhone in the last quarter is quite an amazing feat given the OS has only been available for about 18 months. Google shipped Motorola Droids to all 4,000 Google I/O attendees (including myself) with 30 days pre-paid access via Verizon. My Google G1 phone now seems archaic in comparison and I can't wait for the 2 year Sprint subscription to expire so I can switch over to Verizon and continue using this Moto Droid (I also recently purchased a Verizon MiFi for roaming cloud access and have been very impressed with their coverage)

Moving contacts and calendar events to the cloud is a common first step (I still don't understand why iPhone users tolerate the concept of syncing a device) and the ease of using GMail with Android makes it quite easy for consumers and businesses alike to move to the cloud.

Some key areas/topics I'll be following at the conference:

Chrome OS
I think the formal launch of Chrome OS and ubiquitous distribution through netbook partners will be a next likely step to broaden Google's reach and I expect some exciting announcements about this platform this week.

Android Development
I have the beginnings of an Android app integrated with Salesforce Chatter started, but I need to attain more mastery of debugging techniques, use of the emulator, and package/deployment steps.

Google Apps Marketplace
How to develop for and monetize Google App plugins.
Appirio has a pretty slick demo of embedding a Salesforce widget in Google Mail. I'm hoping Google will open up this API at the conference for others to try it out.

IoT and Google App Engine (GAE)
I'm interested in the potential of using GAE and BigTable as an aggregator for the Internet of Things. One side project I'm working on is to port my Chatter bot to Google.

Chrome Browser and HTML5
Just how far can Javascript be pushed to deliver rich internet applications? I'll be looking for some early indications that Google is serious about implementing HTML5 local storage and video on Chrome.

BI / Google Charts / Visualization
This is a little known API for rendering charts using a RESTful interface and I really dig it. There's great potential for moving business intelligence (BI) apps to the cloud by replicating/aggregating data using GAE and Google charts and visualizations for reporting

Google Sites
As a follow-up to our soon to be released "Cool Sites for AppExchange" app, I'm interested to learn how our template designs can be repurposed for Google Sites.

Google Wave
We've started using Google Wave internally quite a bit internally and it's emerging into an excellent collaboration tool.
Check out some live Google Waves this week. I just may be on some of them :-)

Monday, 17 May 2010 10:58:05 (Pacific Daylight Time, UTC-07:00)
# Friday, 14 May 2010

What if the buildings you worked in could participate in Salesforce Chatter feeds? What if the products you shipped could automatically create Cases in Salesforce when they needed servicing? More objects are becoming embedded with sensors and gaining the ability to communicate. This is enabling the next major advancement in the cloud; the Internet of "Things".

Force.com provides an ideal platform for sensor data with the ability to relate information in the physical world to native or custom objects. My previous blog post on Chatter highlighted the Salesforce user experience and ability for people to interact in the cloud. This post demonstrates using Force.com and Chatter to capture information from objects in the physical world and posting to Chatter feeds using the Chatter web services API.

This application is a very basic Facility Management app. There is a single custom object named "Building" that is comprised of many "Assets", such as Conference Room, Main Entry, Air Conditioner, and Heating System. (See this application in action in the video at the end of this blog post).

Sensors on these assets report their readings to Salesforce in the form of Chatter FeedPost records so that when someone walks into a conference room, the Asset record for that room is updated with Chatter information to the effect of "Motion detected in Conference Room".

The feed posts appear to be created by a Salesforce User named "Environment Bot". This is essentially an API user account for reporting environmental sensor activity.

People can comment on the bot's posts. For example, building maintenance personnel may notice the temperature increasing in some rooms and post comments like "Hey, is anyone on this? The AC appears to be broken on the 3rd floor". Or, a night watchman may notice movement around the Main Entry after business hours and log some comments about what he noticed on patrol. Chatter Bot also has the ability to post pictures and share them as links to Chatter Feeds.

Because the facility management application is utilizing the Chatter API, other Chatter enabled apps may be used to augment and enhance the application. For example, installing the Chatter Timelines application from Ron Hess provides a nice linear visualization of what sensor events occurred and when.

The Chatter Bot is built using an Arduino Duemilanove electronics prototyping platform with Ethernet shield and a Radio Shack breadboard with motion and light sensors.

The Arduino sketch source code just runs in a loop polling the sensors and then notifies Salesforce via a proxy service when environmental changes are detected.

I initially designed the Chatter bot to talk directly to the cloud, but later discovered there are more benefits in having bots communicate through a proxy service to Salesforce.

Industry applications
There are a number of possible industry applications that can leverage this framework:

  • Continuous Emissions Monitoring (CEM) Systems
  • Home / Business Alarm Systems
  • Shipment / Automobile location tracking
  • Environmental Control Systems
  • Healthcare Biosensors

If you'd like to learn more about interfacing Salesforce with the physical world via sensors, then please vote for my proposed session "The Chatter of Things" for Dreamforce in December 2010 to see Chatter Bot live and in action.

The number of objects far exceeds the number of people and there is great potential in using Force.com to enable the Internet of Things. There are many more enhancements I'll be making to this platform. I look forward to sharing them.

This video provides a brief demonstration (4:44) of the Facility Management Chatter Bot in action.

Friday, 14 May 2010 09:46:00 (Pacific Daylight Time, UTC-07:00)
# Thursday, 29 April 2010

The VMForce value proposition:
  1. Download Eclipse and SpringSource
  2. Signup for a Salesforce Development account and define your data model
  3. Write your Java app using objects that serialize to Salesforce
  4. Drag and drop your app onto a VMWare hosted service to Force.com to deploy
The partnership breaks down as:
  1. VMWare hosts your app
  2. Salesforce hosts your database
The 2 are seamlessly integrated so that Java Developers can effectively manage the persistence layer as a black box in the cloud without worrying about setting up an Oracle or MySql database, writing stored procedures, or managing database performance and I/O.

This is all great news for Java Developers. It's yet another storage option on the VMWare cloud (I'm assuming VMWare remains fairly agnostic beyond this relationship and Force.com becomes one of many persistence options to Spring Source developers).

For larger organizations already using Salesforce but developing their custom Java apps, this opens up some new and attractive options.

Existing Salesforce Developers may have wondered if Java would replace Apex and Visualforce, prompting a Salesforce blog post aptly titled "In case you were wondering...". In short, "no". Apex and Visualforce will continue to evolve and be the primary platform for developing Salesforce native apps. I personally will continue to use Apex and Visualforce for all development when the data is stored in Salesforce unless compelling requirements come along to use VMForce (most likely that have particular DNS, bandwidth, or uptime needs).

So why the partnership between VMWare and Salesforce? When Salesforce announced Apex back in 2007 it was met with broad acceptance, but some common criticisms were:
  • Why another DSL (Domain Specific Language)?
  • Why can't I leverage my existing Java skills to write business apps?
  • Salesforce is written in Java. Can I upload my existing Java apps to the cloud?
These criticisms were coupled with some looming 800 pound Gorillas in the room (Amazon and VMWare) pushing virtualization as the basis for cloud computing while Salesforce promoted the non-virtualized, multi-tenant path to cloud computing.

They both can't be right. Or can they? CIO's are being bombarded with virtualization as a viable cloud computing solution, so I think Salesforce has wisely taken a step back and taken a position that says "We do declarative, hosted databases better than anyone else. Go ahead and pursue the virtualization path for your apps and leverage our strength in data management as the back end".

Over time, the bet is that VMForce customers will also discover the declarative configuration tools for form-based CRUD (Create/Read/Update/Delete) apps can meet the rapid prototyping and development needs of most any line of business apps.

For object-oriented developers, Salesforce provides a persistence layer that meets or exceeds any ORM (Object Relational Mapping) or NoSQL solution. The impedance mismatch between objects and relational databases is widely known, and VMForce solves this problem very elegantly.

I think other ORM Developer communities, such as Ruby on Rails Developers, will appreciate what is being offered with VMForce, prompting some to correctly draw parallels between VMForce and Engine Yard.

In my experience working with Azure, I cannot emphasize enough how difficult it was to work through the database and storage aspects on even the most simplest application design. Sure, C# is a dream to work with (compared to both Java and Apex) and ASP.NET works well enough for most applications, but Microsoft leaves so many data modeling and storage decisions to the Developer in the name flexibility, which ultimately means sacrificing simplicity, reliability, and in some cases scalability.

Some final thoughts, observations and questions on VMForce:
  • Are there any debugging improvements when using VMForce relative to Apex/VF?
  • The connection between VMWare and Salesforce is presumably via webservices and not natively hosted in the same datacenter. Does this imply some performance and latency tradeoffs when using VMForce? (Update: No. Per the comment from David Schach, the app VM is running in the same datacenter as the Force.com DB)
  • Licensing: No idea what the pricing will be. Will there be a single biller or will Developers get separate invoices from VMWare and Salesforce for bandwidth/computing and storage?
  • It strikes me as quite simple to develop Customer/Partner portals or eCommerce solutions in Java that skirt the limitations of some Salesforce license models when supporting large named-user/low authentication audiences. Will Salesforce limit the types and numbers of native objects that can be serialized through VMForce?
  • Will VMForce apps be validated and listed on the AppExchange? If so, will they be considered hybrid or native? What security review processes will be enforced?
  • Why only the teaser? Ending a great demo with "and it should be available sometime later this year" just seemed deflating. I think Business Users and Developers respond to this kind of promotion much differently. It would be far better to leave Developers with some early release tools in hand immediately after the announcement and capitalize on the moment. Business Users, however, can be shown Chatter, and other future release features, to satiate their long term interests.

Update:Jesper Joergensen has an excellent blog post that answers many of these questions. Thanks Jesper!

Thursday, 29 April 2010 14:38:34 (Pacific Daylight Time, UTC-07:00)
# Tuesday, 09 March 2010

If you just want the high level summary, I can spare you the time of reading this lengthy blog article and summarize Chatter in the following image.

Salesforce Chatter is basically Facebook for the enterprise and one of the greatest things to come along since sliced bread (besides Jack Bauer). Chatter is a collaboration platform that supports status publishing and the ability to follow people and objects (Salesforce records).

After seeing a Tweet with instructions to email iwantchatter@salesforce.com to participate in the pilot program, I contacted Salesforce and got on the waiting list. I executed some standard legal agreements (Chatter is still considered pre-launch) and Chatter was enabled in our Salesforce org within a couple days. I would suggest "selling" your org in the body of your pilot program request with facts that might help the already overwhelmed Salesforce staff determine which clients might make the best case studies for using Chatter.

Chatter enables the new UI theme, which I've been requesting for several weeks since the launch of Spring '10. Awesome news since this was not available with the initial Spring 10 rollout.

Setting expectations with users.
I was the eager admin excited to get my hands on new features, then it dawned on me that other users might have questions about the change. In a company of < 10 users, this is no big deal. But I'm guessing a larger org may want to do a more methodical rollout.

After enabling Chatter I sent out an email to everyone simply stating "This is going to rock. If you've used Facebook, then you'll understand what the new feature is about. There's also a new theme activated."

Some Salesforce admins on Twitter have suggested just enabling the new UI, setting off the fire alarm as a distraction, then running out of the building. Whatever works! :-) My feeling is that there should be no delay enabling the new UI. The majority of users will love it.

Email Alerts
One feature that really stands out is the ability to receive an email alert whenever certain events occur. I think this is a smart move on Salesforce's part. Each user has the new ability to enable/disable email alerts under Personal Setup "My Chatter Settings".

As much as Google Wave, Wikis, and other social business software may promote the benefits of replacing email with collaboration platforms, it's just never really panned out. There are just too many Outlook and Gmail users out there with investments in email filters and routing rules for driving business process. I left these features enabled (the default setting).

Based on past experience, I had a concern that Chatter emails might eventually overwhelm my inbox (which I have a particular GTD obsession for managing), so before proceeding any further I created a GMail label and filtering rule specifically for Chatter.

Now all emails from "Salesforce Chatter" automatically get tagged and sorted into their own folder in GMail. The equivalent can be easily accomplished in Outlook Rules. This might be a good tip for Salesforce Admins to share in their Chatter rollout email.

Chatter Settings and Feed Tracking

Administrators can define which objects are enabled for Chatter collaboration and which fields on those objects will trigger automatic Chatter updates.

This is a very simple and easy to use 2 panel user interface with Objects on the left and fields on the right. You select which fields will trigger a Chatter alert when modified. The left panel has an excellent UI element that tells you how many fields are being tracked on that particular object, so you don't have to drill down to each object one at a time to identify feed tracking hot spots.

If you've worked with object history tables in Salesforce, you'll be familiar with what this interface is providing. Now with Chatter, in addition to logging history changes, you're also posting messages to the Chatter stream. History table and Chatter feeds are 2 completely separate features, athough they are semantically the same.

Some objects had feed tracking enabled by default. Most did not. Of the ones enabled, they had 2-5 fields already pre-selected. I could not discern any particular pattern as to how or why certain defaults were configured. I'd say the defaults look "balanced" and it does appear that someone put some thought into a reasonable amount of feed traffic on frequently used CRM object/field combinations. There is a "Restore Defaults" link in the right panel of each object. Clicking these restores the defaults.

People and Profile Tabs
One final Administrative step is to add the People and Profile tabs to your main applications. Just as you can view/manage your profile and find your friends in Facebook, Chatter provides Profile and People tabs to accomplish similar tasks.

Chatter will work without these tabs, but users will only be able to incrementally discover other people who comment on particular objects. I added these 2 tabs to all our applications to get the full benefit of Chatter and apply some consistency in the UI. The People tab provides a list view of all "Colleagues" within the Salesforce Org. The Profile tab allows users to define how they appear to other people; including photo, status, and description.

The "Update Photo" feature with image cropper file is probably one of the first features Chatter users will use on the Profile page.

I found it interesting that I could, as a System Administrator, edit other peoples profiles. That initially struck me as "big brother-ish" since I'm so accustomed to passively using social media platforms, and not actually administrating them. The Chatter Profile pages also contain a link to the existing User Detail page template, which I know Admins will appreciate.

One thing I really like about Chatter is that Salesforce didn't complicate the configuration by providing a full access control list (ACL) wrapper with specific Read/Write permissions per object. If you can view a object, you can jump right in and chime in on Chatter without wondering if you only have read only permissions to watch what other people are saying, but not be able to contribute yourself.

Granted somebody at some time likely raised the concern "But what if some CEO only wants employees to read his status messages and not comment on them?". I'm glad Salesforce resisted that level of access permissions in Chatter.

The first introduction to "Following" will likely be on the People page where users are given the opportunity to subscribe to what particular people are posting as their status message. In such a small org, such as ours, you can follow everyone with just a few clicks. But it made me wonder if a "Follow All" button might be handy for larger orgs.

Chatter uses what is commonly referred to as an "asymmetric follow" architecture. In other words, I can follow you but you don't necessarily have to follow me. This is how Twitter works. Facebook, however, uses a symmetric system where we must both mutually agree to be friends to follow each others posts and activities.

It makes sense Salesforce would not want to use Facebook's symmetric following because it's assumed right out of the box all users are colleagues in a single organization. You only need to decide which colleagues activity you want in your stream.

Maybe one day when Chatter is enabled in a Salesforce-to-Salesforce configuration it may be beneficial to limit who is following your activity (for example, would Michael Dell want all his suppliers following his Chatter simply because a SForce-to-SForce bridge was enabled? I'd guess not.... but only Michael can answer that question).

I can see dialogues taking place in the workspace along the lines of "Yeah, I track that industry pretty closely. Follow me on Chatter if you want more information".

Using Chatter
I never really used the Salesforce Home page for much more than reviewing my Tasks lists. 99% of my time in Salesforce has aways been working in records. But that now changes with Chatter since the Home page is the central hub for aggregating all the people and content you are following. The home page is now "the business stream" and the potential opportunity for exploiting its power is huge.

(Note about Screenshot: Yes, Chatter can be pretty boring when you're the first person using it. Fortunately, I have the StanBot API User to keep me company (future post) until adoption catches on with the others :-) )

The first time you drill down on any record details with Chatter feeds enabled you're prompted with some next step options and the option to view a 2 minute video on Chatter.

As developer, we can all appreciate the detail that goes into not only developing a new feature, but also deflecting support calls and questions with simple, easy to understand tutorials and documentation. I give Salesforce 5 out of 5 stars here.

Chatter is so well designed and so very similar to Facebook and other social apps, that I'd be surprised if 80% of Salesforce users couldn't click on "Close", skip the tutorials, and figure out most of Chatter on their own.

Collaboration and Development In The Cloud
While there are many cool features in Chatter, the fact that this platform is hosted in the cloud and can be extended to include pretty much any web service into the business stream is what makes it so powerful. There is no software to install, any Admin can setup Chatter in just a few minutes, and collaboration is baked into the platform as a core feature (ie there's no additional license fee to use Chatter).

Part 2 of my Chatter review will get into the specifics of Chatter enabling existing Salesforce apps and taking a peek into the Chatter API and new types of apps that can be developed. Stay tuned!

Tuesday, 09 March 2010 13:55:26 (Pacific Standard Time, UTC-08:00)
# Thursday, 25 February 2010

The eXtreme Programming Portland user group, XPDX, is going through some changes. Several members want to change the name to something like the Portland Agile Developers Group to reflect the group's openness to a variety of development methodologies.

I happen to love XP and have used it since 1999 as a general framework and reminder of key principles to keep in mind on any software project. XP, Scrum, Kanban, and every other agile development methodology I've researched have so much in common that I felt it was easier and more pragmatic to just stick with a single name rather than appear to be chasing the latest fad.

But Agile has become a very academic topic and apparently the minor differences between the various methodologies are not to be dismissed lightly.

This forced me to reflect on why I, and many many other people, were initially attracted to XP and why interest has waned. The answer suddenly became very obvious to me.

eXtreme Programming, at one time, promoted "extreme" ideas that challenged the status quo. It was easy to fill a room with 50+ people who wanted a revolution. And the revolution was successful. Most XP best practices are no longer "extreme". We take many XP and Agile practices for granted now. In fact, Agile is now the new status quo!

It's actually pretty boring to attend or present at an agile group meeting and rehash the same ideas. Attendance is way down. So, if changing a group name is a branding effort to increase attendance, I don't believe that will succeed. Sure, it may draw 3-5 more people like an "Under New Management" sign outside an old restaurant, but it won't change the fact that the same old stuff is on the menu.

An aura of infantilism is creeping into Agile. Agile Coaches and Practitoners now seem more like parents than mentors. Agile meeting topics are increasingly about games and tactics that have short term productivity gains of bringing teams around a single purpose. When I ask presenters about the longevity of their agile teams or the software they produced, it's rare to encounter an answer over 6 months, leading me to believe many agile projects are getting by on the initial "honeymoon" inertia before reality sinks in. All successful software projects are ultimately faced with what seems like a daunting and unachievable task that puts tremendous pressure on the team. What a team does at that inflection point is the true test of "agility".

In many cases, Agile practitioners don't even code or have not evolved their skills beyond 1999 object oriented programming techniques. If practitioners spent more time coding, they would have a sense of the new revolution and extreme ideas that are brewing.

OK. So that's out of the way. My intent is not to push people away, but to pull them towards a new way of thinking. I titled this post to promote forward thinking, so let's switch gears.

If XP was extreme in 2000 by virtue of challenging the status quo, then what is extreme in 2010? Many of the following ideas may be tough to accept. If any of these ideas make you feel uncomfortable, threatened or obsolete, then you may be part of the current status quo. But trust me, these ideas are getting traction and are not going away. The sooner we as a development community embrace these changes, the more relevant our meetings will become.

"Feature Democratization"
XPs core tenet of achieving customer satisfaction through customer driven feature stories has evolved in 2010 to make use of idea voting sites. The customer is now the product manager and has become very involved with providing ideas, feature requests, and UI mockups.

"The 24 Hour Iteration"
The recent launch of Google Buzz had millions of people up in arms over privacy concerns while others applauded the new feature. Google had to act fast and update the software within 24 hours in response to the first wave of customer feedback. This was not a "patch". This was an extremely compressed iteration backed by a process that supports this kind of change. Developing in the cloud is living on the extreme.

"Writers Write"
Software Development is not a 9 to 5 job. Many people go home then build websites for their churches, contribute to open source projects, or just simply enjoy programming over the weekends. A personal growth goal for some Developers is to develop their own style, much like a literary writer. The days of seeking validation from a venture capitalist to pursue an idea are over. We don't all need to conform to a universal set of rules or conventions when writing software.

"No Outsourcing"
Great software development projects are not outsourced. No more than a great video game title, movie, song, or book gets outsourced. Let's get over the false idea that software development is an easily outsourced task and embrace the uniqueness and originality any person or team can contribute.

"No SQL"
Many greenfield projects are breaking away from the long history of using relational data stores. The NoSQL movement is developing applications faster and more scalable by sacrificing relational features like JOIN. Many NoSQL projects have characteristics similar to early object oriented database solutions.

"All Javascript All The Time"
A little Javascript in a product like Google Maps can go a long way. Taking this to the extreme and developing entire products in Javascript, such as Google Apps and Microsoft's upcoming Web Office 2010, requires a different approach to software development. New layers of abstraction like GWT, Closure, and JQuery should be explored and embraced by anyone working on web applications.

"See The Forest For The Trees"
Really not an extreme idea, but one I think has been lost. When agile discussions quickly devolve into focusing on a small detail and make an academic issue out of the process, the survivalist in me says "Yeah that's great, but let's not lose sight of the big picture". Maybe the "big picture" just can't be coached. A good team needs to internalize the value being received by the customers and, ideally, be a consumer themselves of what they're developing. How do people discover software? What compels them to try it? What is the install/config process like? Why would they stay engaged? Can game mechanics can be added? How can the customer be given a voice and opportunity to participate in the evolution of the software? For agile teams, this process is "fun". For other teams, the Developers actually need to be told what to do, how to do it, and when to deliver it.

"Work from home / Distributed collaboration"
The essence of pair programming is to collaborate with other Developers on a single task. In reality, most software is not written with 2 Developers physically in the same space. The Internet allows for more distributed collaboration opportunities in 2010. How are successful projects taking this to an extreme and using this to their advantage?

"Quit Unit Testing and Write Better Code"
Unit testing is largely used in object oriented projects as a check on the side effects and loose contracts inherent in OOP. Design by Contract and Functional Programming have evolved (actually FP has been around quite awhile) to address these quality issues up front. One extreme idea is to "not do unit testing" and actually improve the quality of code by removing side effects with functional programming and using design by contract for runtime enforcement. Several agile projects with tons of unit tests just end up being "well tested crap". What's wrong? Unit testing is not a silver bullet. Let's get that out on the table.

"Pair Programming Sucks"
Let's face it. When 2 people with compatible coding and social skills work together, they'll produce something well beyond what they'd create on their own. If the pair is not compatible, then the code will suffer and they'll possibly make life worse for others around them. You can't "coach" people to work together. Dogmatic pairing of programmers cannot be universally applied to all projects. Good teams and collaborations take time to develop.

"Develop In The Cloud"
Do you really need to spend an iteration "0" setting up servers, getting everyone's desktop on the same version, and installing a database? Once the project goes live do you want to take a 3am call to address a load balancing bug? If you encounter any measure of success, are you really prepared to scale and meet the demand of that success? The status quo says "Yes, how else will get ROI from the datacenter we just built?". The extreme programmer would say "No way. Writers write. You handle the rest".

"Federated Cloud"
We've all been conditioned to avoid "Vendor lock-in" when making a significant investment in IT infrastructure, but are we making the same mistakes as more software development moves to the cloud? Will all software eventually run on one of 4 large datacenters? The cloud was built on open source. Now the open source movement needs to be revitalized in the cloud, move beyond HTTP/SMTP, and federate a more abstract layer on the Internet using open source.

"Bootstrap to Success"
How relevant is a Computer Science degree or VC funding in your decision to using software? Anyone can develop great software and become financially independent using proven bootstrapping techniques and the Internet as a distribution channel.

I've itemized just over a dozen extreme ideas here. There are many more. Do XP groups need re-branding or does XP itself need to be redefined to take on new extremes? Should we recalibrate and invoke XP's FixIt rule?

If even one other person in Portland wants to discuss these ideas, I'd be happy to meet over a Beer (or two) to explore the "new extremes" on a regular basis.

Comments? Ideas? Suggestions?

Thursday, 25 February 2010 12:08:06 (Pacific Standard Time, UTC-08:00)
# Monday, 22 February 2010

I'm presenting "Developing In The Cloud" at the Portland JavaScript Admirers Group this month. If you're in Portland this Wednesday, February 24th, 2010, come check it out 7pm-10pm!

The talking points are below. There'll be several visual examples and live coding demonstrations.

Monday, 22 February 2010 10:40:29 (Pacific Standard Time, UTC-08:00)
# Sunday, 21 February 2010

There are several bank specific rules for validating credit cards, but all card numbers can be validated using the Luhn algorithm. The Luhn algorithm, aka the Luhn formula or "modulus 10" algorithm, is a simple checksum formula used to validate a variety of identification numbers.

It is not intended to be a cryptographically secure hash function; it was designed to protect against accidental errors, not malicious attacks. Most credit cards and many government identification numbers use the algorithm as a simple method of distinguishing valid numbers from collections of random digits.

Programmers accustomed to using '%' as a modulus operator need only to shift gears slightly and use the Math.mod(int1, int2) library function when working with Apex.

public static boolean isValidCheckSum(List<integer> numbers){
	integer sum = 0;
	integer len = numbers.size();
	for (integer i = len - 1; i >= 0; i--)
		if (math.mod(i , 2) == math.mod(len,  2) )
			integer n = numbers[i] * 2;
			sum += (n / 10) + ( math.mod(n, 10));
			sum += numbers[i];
	return ( math.mod( sum, 10) == 0 );
Sunday, 21 February 2010 12:15:00 (Pacific Standard Time, UTC-08:00)
# Tuesday, 16 February 2010

I spent a few hours tackling this problem, so hopefully this blog post will spare someone else the difficulty of using Salesforce Spring '10 features before it is broadly released.

Spring '10, aka version 18, is a big release for Salesforce Developers. The current version of Eclipse Force IDE defaults to using the version 16 API.

Once Spring '10 was installed on my org (NA1) I committed to using the v18 features on a couple new projects. Unfortunately the Spring '10 release hit a snag, so now the release is being staggered over 30-45 days and the new Force IDE release has been put on hold.

Fortunately, there are a couple workarounds to using the v18 API and features today.

Option 1)
a) Create an Apex class as you normally would in Eclipse and accept version 16 as the default.
b) Eclipse will create a second file next to the class with a 'meta.xml' extension.
c) Edit the -meta.xml file by changing the version to 18 then save.

Option 2)
a) Create an Apex class through the Salesforce browser interface but do not accept the default version 18. Instead, select version 16.
b) Open the Salesforce project in Eclipse and confirm the Apex class is available in the IDE (the current IDE apparently won't automatically sync with classes > v16. At least that was my experience).
c) Back in the Salesforce browser, change the version from 16 to 18.

Finally, depending on which approach used, you'll need to synchronize the Eclipse IDE with Salesforce servers using either the "Deploy to" or "Refresh from" server options by right clicking on the class and selecting from the Force.com option. (Option 1 requires "Deploy to". Option 2 "Refresh from").

Hope this helps!

Tuesday, 16 February 2010 18:28:19 (Pacific Standard Time, UTC-08:00)