Programming, technology, and CRM – from a Belgian programmer exiled to Missouri
  • rss
  • Home
  • Soft Gallery
    • autosvnbackup.sh
    • VBScript Snippets
  • Contact Me
  • Welcome

Ad-hoc REST services on the force.com platform

Nicolas Galler | December 5, 2010

Note – as of Summer ’11 there is a much better solution in the form of Javascript Remoting. I am leaving the information below for reference but do not recommend using it.


Force.com is coming up with a REST style api to access the data from 3rd party applications, widgets etc. While this is great news as this type of web services is a lot easier to access than traditional SOAP calls from many programming languages (including obviously the important Javascript), it should not be forgotten that it has been possible for a while already to create your own, custom REST-style services – very useful when trying to make a page more responsive by coding certain areas in Javascript with AJAX calls. These don’t benefit from the OAuth authentication so they are more useful for pages that are accessed by already authenticated users. One advantage is that as they are very specialized you can make the payload as lean as necessary. One drawback is that as the facilities of the native Force.com programming environment are a bit rudimentary there is a certain amount of boiler-plate code involved.

The controller side looks like a usual controller, typically using the query-string or form parameters in the constructor to build a result which is then available to the view. The view can loop over that result and output it in JSON format using the built-in JsEncode function. For example here is a simple contact search service:

public with sharing class SearchServiceController {
	/**
	 * Array containing the results.
	 */
	public Contact[] Matches { get; private set; }

        /*
         * grab the parameter from the page's and run the search.
         */
        public void executeSearch() {
		String name = ApexPages.currentPage().getParameters().get('name');
		executeSearch(name);
        }

	/**
	 * Run the search with the specified parameters, populating the Matches variable.
	 */
	public void executeSearch(String name){
		Matches = [select Id, Name, MailingStreet, MailingCity, Mailing State from Contact where LastName=:name];
        }
}

Then the view could look something like this… most modern programming languages have constructs for automatically serializing to JSON nowadays, but not Apex – still, it’s not that hard to get the same result on the view:

<apex:page contentType="text/javascript" controller="ProximitySearchServiceController" action="{!executeSearch}" >
<apex:variable var="rowIndex" value="{!0}"/>
{"result":[
    <apex:repeat value="{!Matches}" var="contact" >
        <apex:outputText rendered="{!rowIndex != 0}" value=","/>
        {"name":"{!JsEncode(contact.Name)}",
         "address1":"{!JsEncode(contact.MailingStreet)}",
         "city":"{!JsEncode(contact.MailingCity)}",
         "state":"{!JsEncode(contact.MailingState)}" }
         <apex:variable var="rowIndex" value="{!rowIndex+1}"/>
    </apex:repeat>
]}
</apex:page>

Not exactly rocket science, but that’s kind of the point: the beauty of REST is that it simply leverages the existing HTTP protocol without the added baggage (both in payload and complexity) of an RPC protocol. Perhaps the only tricky part in the force.com version is the output of the comma in the right position (remember a trailing comma in a list works fine in FireFox but not in IE). There is no out of the box facility for getting the row index in the repeater. Also, don’t forget to set the contentType so that the default page headers don’t get included. And don’t forget to disable the development mode on the page… other, the HTML for the page editor will still get sent and mess with the JSON output!

Lastly a little security note… such services are not wide open because they require the user to be logged into Salesforce. However, it is possible for an attacker who controls a web site that is visited by a Salesforce user to submit a request on their behalf (including their authentication cookies). They won’t be able to retrieve the results, but if the service causes an update or an insert that could happen. If it’s a concern (e.g. for an ordering system) you can check the HTTP referer using ApexPages.currentPage().getHeaders().get(‘Referer’), and make sure it comes from an expected site / page. Some good notes about that on the force.com blog.

Comments
No Comments »
Categories
Force.com
Comments rss Comments rss
Trackback Trackback

(mis)adventures with the Dojo build system

Nicolas Galler | December 5, 2010

Dojo has this amazing tool as part of their framework which is kind of a all-in-one shop for all your Javascript and CSS optimization needs. It’s called the Dojo Build System. It uses the dojo.require statements that are part of the module definition to figure out the combination of Javascript files that will include everything needed, but not more, to minimize both the total size of data transferred and the number of connections necessary to do so.

Overall it works great and there are a few good examples that show how to use it as part of their documentation. I did run into a few pitfalls mostly due to the assumption it makes about the directory layout which I thought I should document here for the benefit of Google and Nick-from-the-future.

  1. Although not mentioned explicitly, if you specify a CSS optimization level, the tool will optimize all CSS files it finds in the folder. I spent a while looking for a switch that would let me specify which CSS files to pick up before realizing that.
  2. A little catch: the output of the Javascript optimization is to be found under the “release/dojo” folder, not “release/yourmodule” as you might expect.
  3. It is quite sensitive to syntax errors and the error messages are really not very good… so make sure the Javascript in the files is all good… especially when you also take into account the fact that the tool takes a while to run because it re-processes the whole Dojo distribution every time (I wish there was a way to do an incremental build but I have not figured out how).
  4. The tool must be run from within the correct folder (util/buildscripts in the dojo source distro). Most of the examples in the documentation have you place your module folder (or create a symlink to it) within the dojo source folder… this is pretty messy and confusing, and makes the upgrade of dojo harder because if you pick up a new release you have to remember to create the appropriate symlinks. There is however an example directory layout that works well and keeps things separated on DojoCampus. They also provide a sample shell script there that makes invoking the tool a lot easier. It is also good to show the various important parameters for the build.
  5. Along the same lines: be careful with symlink, as the tool does a lot of “..” to get to the various files… so if the folder is a symlink the tool might walk itself out of the directory structure.
  6. Even once the Javascript file is flattened, one thing to remember is the localization messages are still loaded separately (the assumption is that the system won’t know what language to load until runtime). If desired (if only one language is needed) it can be concatenated to the output file, and then the locale can be fixed in the djConfig parameter.
  7. Finally, an error that I spent quite a while to debug: if the “releaseDir” contains a “..” in its path, then the build errors out with:
    js: "./jslib/i18nUtil.js#61(eval)", line 1: uncaught JavaScript runtime exception: SyntaxError: missing name after . operator
    
    js: dijit..var.www.nicocrm.test.spx....spxRelease.release.dijit._editor
    

    Oh well, now I know. Apparently there is a similar bug misfeature if you include a backslash on the path name (if you do the build on Windows). I can’t speak for that one for sure as I only tried it on Linux so far.

Once I got past those problems all was good – inline CSS and Javascript, inline templates, all comments stripped, and the Javascript is compressed. You should only need 2 scripts included per page: the “base” dojo.js which is normally included on every page thus will be cached, and the “layer” script which is created based on the modules that are needed on that specific page. For CSS you might have 3 files: the base dojo.css, the theme, and the layer file (I suppose you might combine the theme and base dojo stylesheets, for an even more optimized build). Unfortunately however the tool does not appear to do CSS sprite optimization yet.

Comments
2 Comments »
Categories
Dojo
Comments rss Comments rss
Trackback Trackback

Categories

  • Dojo (1)
  • Experiments (4)
  • Force.com (2)
  • Interesting (1)
  • Javascript (3)
  • MSCRM (1)
  • Programming (63)
  • Rant (3)
  • Saleslogix (41)
  • Tricks (8)
  • Uncategorized (32)

Post History

  • 2011
    • January (3)
    • February (2)
    • March (1)
  • 2010
    • January (3)
    • March (3)
    • April (2)
    • August (2)
    • October (4)
    • November (1)
    • December (2)
  • 2009
    • March (2)
    • April (1)
    • May (3)
    • June (3)
    • July (1)
    • September (3)
    • October (2)
    • December (5)
  • 2008
    • January (9)
    • February (4)
    • March (9)
    • April (1)
    • May (5)
    • June (8)
    • July (1)
    • August (2)
    • September (1)
    • November (1)
    • December (3)
  • 2007
    • January (3)
    • February (7)
    • March (1)
    • April (3)
    • May (6)
    • June (2)
    • July (1)
    • August (2)
    • September (5)
    • October (3)
    • November (5)
    • December (4)
  • 2006
    • January (2)
    • September (1)
    • November (3)
    • December (4)
  • 2005
    • April (1)

Meta

  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org
rss Comments rss valid xhtml 1.1 design by jide powered by Wordpress get firefox