Simon Fell > Its just code > Web Services

Monday, November 12, 2007

Don Box on Auth

I found it hilarious that Don moans about HTTP auth and then points to WS-Security as the way forward, I just can't decide if Don was trying to be funny, or is actually serious. (in which case he's been in Redmond too long), looks like I'm not the only one.

< 8:19 AM PST # > tags : Web Services [playing "Swamp Thing" by Juno Reactor (from Bible of Dreams)]

Friday, May 04, 2007

Salesforce Developers Conference

Is coming up fast, May 21st in Santa Clara, CA. This is a great chance to get up to speed with Apex Code, and other parts of the Salesforce.com platform, As well as the regular ADN crew, I'll be there along with some other folks from the API team, so bring your Apex Code, API and Web Services questions, best chance to get answers straight from the horse's mouth before Dreamforce. Best of all, its Free, sign up now.

< 9:35 AM PDT # > tags : Salesforce.com Web Services

Saturday, April 28, 2007

Team Hanselman and Diabetes Walk 2007
Scott Hanselman is again doing the Diabetes Walk, and this year is stepping up his goal to $50,000, go ahead and help him meet the goal. To the Salesforce.com folks out there, remember that they'll match your contribution, and I'm sure many other employers do as well, an easy way to make your money go twice as far.
< 6:15 PM PDT # > tags : .NET Salesforce.com Technology Web Services

Thursday, April 05, 2007

The devil is in the wrong details.

Paul Fremantle has a post titled the devil is in the details, where he discussed interop issues around wrapped vs unwrapped WSDLs. Unfortunately that's totally missing the point, Why on earth should the service provider get to dictate to me what programming model i want to use? why do the tools insist on trying to divine a programming model from the WSDL, when it should be the programmers choice!, give me a switch in WSDL2Java or wsdl.exe that says generate me a wrapper or unwrapped stub.

< 8:26 AM PDT # > tags : Web Services [playing "Fit But You Know It" by The Streets (from A Grand Don't Come For Free [UK])]

Monday, February 12, 2007

Outbound Messaging with .NET 1.1

As I mentioned way back in April 2003, wsdl.exe /server is basically useless. This is fixed in .NET 2.0, and wsdl.exe /serverInterface works pretty much as you'd expect (or at as I'd expect, which is good enough for me). If you're trying to use the new Outbound Messaging feature that was part of the recent Winter release, and you're still on .NET 1.1, then you'll run into this real fast. For those who haven't seen the feature, basically you specify some condition to send you a message, you define what fields you want in the message from the target object, and we generate a WSDL that represents the messages we'll send you. You feed this wsdl into your tool of choice to spit out your server skeleton, and off you go. Well, unless you're on .NET 1.1, where its not remotely obvious what to do. So, here's a quick guide to getting up and running with Outbound Messaging and .NET 1.1.

A slightly cleaner approach is to actually do the subclass, and to copy over all the class and method attributes to the subclass as well, at least then you can easily re-run wsdl.exe if you need to (say if you changed the set of selected fields).

< 11:43 PM PST # > tags : .NET Salesforce.com Web Services

Saturday, January 27, 2007

PocketHTTP updated

The release train rolls on, I just posted an updated version of PocketHTTP to address a couple of issues, (i) you could still get bogus gzip errors because under certain conditions it would apply the crc calc out of order and (ii) there was an issue with how the connection pool managed proxied SSL connections, that would result in it giving you the wrong connection if you trying to do proxied ssl to multiple different target hosts.

< 1:41 PM PST # > tags : PocketHTTP Web Services

Wednesday, January 17, 2007

Apex Web Services

I was at Apex day in San Francisco yesterday, there was an impressive turn-out, I saw lots of new faces, along with a few familiar faces from Dreamforce. Developer's at the event were lucky enough to be able to signup for the developer prerelease of Apex Code. In addition to the support for triggers that Apex Code brings, Apex Code also supports exposing your code as a fully fledged web service, complete with WSDL, and powered by the same high performance, highly interoperable web services implementation that drives the primary salesforce.com API. In Apex code the private/public specifier has an additional option, its actually private/public/webService. Simply create your code in a package, and mark the method as webService, e.g.

package wsDemo {
    webService String sayHello(String name) {
        return 'Hello ' + name;
    }
}
and you'll have a complete WSDL for calling this code. Of course, no one needs a web service to do string concatenation, where this really comes into its own is build your own transactional units for doing integrations. Anyone who's built a complex data integration with salesforce (or any other distributed system) knows the pain of trying to manage transactional units that are different at the both ends, and having to build compensating transactions etc. Simple examples like creating an opportunity and all its line items in a single transactional unit could of been achieved by evolving the existing API, however more complex uses cases, where the developer needs to update 5 objects, delete 3 and create 1 new object all in a single transaction, just can't be handled by evolving the existing API. But, now you can build your own API's that have exactly the transactional boundaries you want. In Apex Code, you the developer control the transactions, so you can write a method that receives all the data needed as inputs, it can do a number of data operations, including create, update, delete, using data from both the request, and existing data in the system, then at the end only commit if everything went ok. Using Apex Code with its Web Services support I think will be a really powerful and easy way to do complex data integrations. Here's an Opportunity / LineItem sample, as the calls to insert will throw an exception if there's an error, and if the exception leaves your code, your transaction is rolled back, the entire call will either fully succeed or fail.
webService ID createOrder(Opportunity o, OpportunityLineItem [] items) {
   insert(o);
   for (OpportunityLineItem i : items) {
      i.opportunityId = o.Id;
   }
   insert(items);
   return o.Id;
}
< 9:40 PM PST # > tags : Salesforce.com Web Services

Sunday, December 24, 2006

new builds

Couple of new builds out with some minor bugs fixes, first up, a new build of PocketHTTP that fixes an intermittent problem some people had seen when its reading gzip compressed responses. Second up, an update to SF3, this fixes a problem caused by a particular combination of contact details in address book on initial sync, it also addresses a problem with reading all day events from salesforce and them ending up with the wrong date in iCal. Next time you start SF3 it'll tell you about (and offer to install) the updated version, assuming you left the check for updates preference on. Right now I'm suffering from having way more idea's than time to work on them. Happy Holidays!

< 1:11 PM PST # > tags : OSX PocketHTTP Salesforce.com Web Services [playing "Give Da Jew Girl Toys (Dirty)" by A plus D (from Santastic II: Clausome)]

Thursday, December 07, 2006

Compression in .NET 2.0 Web Services Clients

Over on ADN there's a tech note that explains how to add request & response compression support to .NET generated web services clients. As .NET 2.0 provides support for response compression out the box now (once you've turned it on), you'll find this code fails on .NET 2.0 because it ends up trying to decompress the response twice. So I updated the code for .NET 2.0, it now only has to handle compressing the request. The nice thing about the approach it takes (subclassing the generated proxy class), is that you don't have to change the generated code at all, so it doesn't matter how many times you do update web reference, you'll still be in compressed goodness. So, all you need is this one subclass wrapper around your generated proxy class and you're good to go.

    class SforceGzip : sforce.SforceService
    {
        public SforceGzip()
        {
            this.EnableDecompression = true;
        }

        protected override System.Net.WebRequest GetWebRequest(Uri uri)
        {
            return new GzipWebRequest(base.GetWebRequest(uri));
        }
    }

Then in your code that uses the proxy, just create an instance of this puppy instead of the regular proxy, e.g.

    sforce.SforceService svc = new SforceGzip();
    sforce.LoginResult lr = svc.login(args[0], args[1]);

All this is included in the sample project in the download, share and enjoy, share and enjoy

< 9:03 PM PST # > tags : .NET Salesforce.com Web Services

Tuesday, November 28, 2006

API Authentication List

Scott over at Perspectives on Salesforce has a post about an API Authentication List feature, a way to restrict what API based applications can do. This is something I've been thinking about a lot, allowing application white listing (i.e. you can use Outlook Edition and Offline, but not the data loader or sf3), or Application X only requires access to accounts, make sure that's all it can access. All great ideas and features, but wait, how can the API server tell that the application making the request is in fact Outlook Edition and not SoqlXplorer ? The problem is that while you can authenticate a person, authenticating an application it impossible to do 100% securely (unless the client OS has TPM, and it can authenticate the application for you).

In his idea's exchange entry, Scott has a screen shot from Flickr which provides some similar features. If you go look at the Flickr authentication spec you'll see that it identifies applications using a shared secret, this secret never goes over the wire, so that's good, and if the application is another web based application, then its reasonable to assume that the secret is reasonably secret, you've got to hack the web app server to try and find the secret. However for desktop client applications, that shared secret has to be on the client machine somewhere, and in that case, its not reasonable to assume its safe, any determined person will be able to dig the secret out of where ever you've stashed it away. (and today's threat model is that it only take one determined person to work it out and post it for all to find, not that everyone has to work it out themselves)

Is that secure enough? I don't know, it largely depends on what you're trying to prevent. To stop people trying out random applications on their production data, yeah, I'd think so. To stop a 3rd party application stealing all your data? not if they were determined enough, to stop a disgruntled employee who's about to quit and want to take a copy of all the sales data with them? would likely depend on how well they can drive google. What other options are there? well a blanket profile level API access enabled yay / nay would work, although I'd suspect this is only useful in a fairly small subset of cases.

< 1:16 PM PST # > tags : Salesforce.com Web Services [playing "Belfast" by Orbital (from Orbital)]

Tuesday, November 21, 2006

zkSforce

I ended up building my own Cocoa client library for accessing the Salesforce.com API, I decided a while back I'd open source this, I just posted the first version. This is the library that powers both SoqlXplorer and SF3. Its released under the uber liberal MIT license, so have at it. Feedback welcome.

< 9:33 PM PST # > tags : OSX Salesforce.com Web Services [playing "Doorway [Gridlok + Echo Remix]" by Usual Suspects (from Dungeonmaster's Guide Disc 1)]

Thursday, November 16, 2006

SoqlXplorer

SoqlXplorer 0.7 is out, it include the fruits of the UI rework labor, and of course the new schema explorer. If you have an older build installed, you fire it up and it'll prompt you to upgrade and do all the work for you.

< 11:56 PM PST # > tags : OSX Salesforce.com Web Services [playing "Time Becomes" by Orbital (from Orbital 2)]

Wednesday, November 08, 2006

.NET headers remix edition

In his post Trade-Offs, Sam points to my post last year on trying to have SOAP headers with simple types in .NET. In the comments Asbjørn Ulsberg claims that the behavior is related to handling nulls, and that its fixed in .NET 2.0. Well, lets see shall we.

To start with, the header defined is not nillable, therefore that's a complete read herring. as a reminder, here's the element definition that's detailed in the post and in the WSDL.

<s:element name="ValidFrom" type="s:dateTime"/>

I fired up .NET 2.0's WSDL.exe tool and pointed it at the first wsdl (you can play along at home if you want to)

C:\sampleCode\dotnet20_headers>wsdl http://www.pocketsoap.com/weblog/2005/08/test_1header.wsdl
Microsoft (R) Web Services Description Language Utility
[Microsoft (R) .NET Framework, Version 2.0.50727.42]
Copyright (C) Microsoft Corporation. All rights reserved.
Writing file 'C:\sampleCode\dotnet20_headers\TestService.cs'.
And lets take a look at the generated code
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.w3.org/2001/XMLSchema")]
[System.Xml.Serialization.XmlRootAttribute("ValidFrom", Namespace="http://test.sforce.com/", IsNullable=false)]
public partial class dateTime : System.Web.Services.Protocols.SoapHeader {
    
    private string[] textField;
    
    /// 
    [System.Xml.Serialization.XmlTextAttribute()]
    public string[] Text {
        get {
            return this.textField;
        }
        set {
            this.textField = value;
        }
    }
}
Looks remarkably like the .NET 1.1 version (except for the fields vs properties thing), so, no, not fixed, not any better.

< 8:52 AM PST # > tags : .NET Web Services [playing "Confidence Man" by Jeff Healey Band (from See the Light)]

Thursday, October 26, 2006

SOAP Interop - the devil's still in the details

Apparently the problem with .NET remoting putting char 0 in a fault message from 4.5 years ago is still an issue. (and no, there's still no magic switch to allow PocketSOAP to parse stuff that looks like it might be XML, but isn't XML).

< 9:08 AM PDT # > tags : .NET Web Services [playing "Shadows" by Blue Man Group (from Audio)]

Thursday, October 12, 2006

Dreamforce wrap up

Dreamforce is over for another year, a hectic, fun packed few days, the highlights for me were

See you next year!

< 9:25 PM PDT # > tags : Salesforce.com Web Services [playing "Unstoppable" by Public Enemy (from He Got Game)]