Friday, August 15, 2008

Keep It Simple...

Programming is like sex. One mistake and you have to support it for the rest of your life.
~Michael Sinz

I was in the process of reviewing some documentation for a bit of popular legal software my employer purchased a while back, when I stumbled upon an interesting tidbit. I recognized it immediately for what it was, but I'll get into that a bit later. 

This particular vendor provides a RESTful API into their offerings. When invoking several of said API's methods, you can specify, as a parameter, a contactId in either one of two formats, termed Windows and Web.

The Windows format looks like this: 2/2195. Essentially two numbers delimited by a slash. Easy enough!

The Web format, on the other hand, looks like this: 8589936787.

So, to call their RESTful findContacts method, I would pass one of these two formats, thusly:

http://…/findContacts?contactId=[insert contact id here]

Reading further, I discovered that the Web format is actually a fancy calculation computed against the parts of the Windows format, thusly:

  • Source ID = 2
  • ID = 2195
  • Web ID = (2 * 2^32) + 2195

The result of that calculation would give us the longer Web format: 8589936787.

According to the documentation, this was recently added as a "feature", which I suppose could be marketed as "slashless Web Ids". But, as far as mine eyes can see, really adds no value to the application. 

What it does offer is oodles of cyclomatic complexity, the extent of which may not be apparent at first glance. Let's take a closer look:
  1. Following this change, all developers on the project need to be educated that IDs can be input in two different ways. Why do they need to be aware? So that they don't assume that all IDs going forward will contain a slash, and can revise the way they handle ID input. Maybe they need to call a different function to parse IDs. Maybe they don't need to do anything at all. But I'm betting that somebody, somewhere, will either need to send an email about this change, spend an hour discussing it in a meeting, or add it to the project's internal documentation.
  2. The test cases developed before this change are no longer valid for testing ID input. Now you have to test the case where ID input doesn't contain a slash (the Windows format), as well as the detection of the ID input format (i.e. running different code based on whether the ID contains a slash or not).
  3. In this case, a new web method was developed, convertDualId, which does the math for any math-challenged developers out there. Something else that needs to be tested.
  4. The documentation I'm reading contains three (3) HTML (.chm file) pages of documentation on this topic, explaining the difference between the two formats, and how to do the math to calculate the Web Id if you don't want to call the new convertDualId method. All of which needs to be validated, proofread, and so on.

And all that for... what? Seriously. To calculate the Web Id, I still need to have the two original slash-delimited values, so what am I gaining? I'll tell you what I'm gaining: an id that doesn't contain a slash.

Woop-te-doo.

If a slash is bothering you that bad, I can think of several other much simpler alternatives. Like, say, just HTML-encoding the thing as %2F. But of course that wouldn't properly showcase the developer's creativity, virility, and prowess.

And therefore I must conclude that what this is, in fact, is gold plating at its finest. An anonymous developer's proud signature, showcasing his unique ability to do maths.

Hardly aware is he that writing code like this is akin to locking a ball and chain around his ankle, forcing him into supporting this unnecessary code until the end of time. Or at least until he realizes what he's done and leaves for unspoiled pastures.

Keep It Simple, Stupid.

Sunday, August 10, 2008

xmlns='' was not expected

If you ever run into this XmlSerializer error: it's thrown because the name of the class being deserialized and the root node are not the same.

For example, if you're deserializing XML that looks something like this...
<PersonData>
<FirstName>Bob</FirstName>
<LastName>Black</LastName>
</PersonData>


...into a class called...


public class PersonDataXml
{
...
}


...you'll get this error.

To resolve, just add the XmlRootAttribute to your class, thusly...


[XmlRoot( "PersonData" )]
public class PersonDataXml
{
...
}



Now XmlSerializer won't get all confused.



Friday, August 8, 2008

REST vs. SOAP

I really hate this darn machine;
I wish that they would sell it.
It won't do what I want it to,
but only what I tell it.

~Author Unknown

My intent for this post is to be a 5 minute primer on the major differences between REST and SOAP. Of course, some folk may find a short post inadequate to discuss this particular topic, but hopefully many of you will find this helpful in some way. Before we get started, I'd like to point out that there are many alternatives to these two technologies that won't get discussed here, including (but not limited to) Binary XML, DCOM, CORBA, ICE, .Net Remoting, etc, each of which have their own unique advantages and disadvantages. REST and SOAP, however, are likely the more well-known and more accessible (i.e. easy to pick up).

A look at SOAP

The acronym SOAP was originally defined as Simple Object Access Protocol, but as of version 1.2 of the standard that meaning was dropped in favor of the (allegedly) more accurate Service Oriented Architecture Protocol. SOAP is an XML based protocol which provides for the passing of messages over a network, from computer to computer. In my humble opinion, the original acronym provides a more accurate description of its use today as an IT Enterprise solution for object transfer. But for the purest out there, allow me to clarify that SOAP does not pass objects over the wire, but messages.

Here's a sample SOAP request ("borrowed" from w3schools.com), which requests the current stock price for ticker symbol IBM:

<?xml version="1.0"?>
<
soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
  <
soap:Bodyxmlns:m="http://www.example.org/stock">
    <
m:GetStockPrice>
      <
m:StockName>IBM</m:StockName>
    </
m:GetStockPrice>
  </
soap:Body>
</
soap:Envelope>

And the response would look something like this:

<?xml version="1.0"?>
<
soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
  <
soap:Bodyxmlns:m="http://www.example.org/stock">
    <
m:GetStockPriceResponse>
      <
m:Price>34.5</m:Price>
    </
m:GetStockPriceResponse>
  </
soap:Body>
</
soap:Envelope>

SOAP is obviously very verbose. But it's approach is also very object-oriented, which makes it easy for most object-oriented developers to wrap their brains around. A SOAP service could be considered an object, which contains several methods that can be invoked, or properties that describe the object. If we used .Net to create a proxy class to call this web service, the C# code to invoke the GetStockPrice method might be something like this...

StockService service = new StockService();


float currentStockPrice = service.GetStockPriceResponse();


Console.WriteLine("Current stock price: {0}", currentStockPrice);


I'm using .Net here mainly to illustrate my point, which is that calling a web service looks and feels very object oriented. Even though we're not actually passing objects over the wire, it feels like we are, and so it's easy to work with.


A look at Representational State Transfer (REST)


In its most basic form, a RESTful service is "just" a URL that provides access to a resource. For example, a RESTful URL to get Apple's latest stock price might look something like this:


http://URI/CurrentStockPrice/AAPL/


Or maybe like this:


http://URI/CurrentStockPrice?AAPL


The World Wide Web is the most oft-cited example of RESTful design. Web pages support POST, GET, PUT, and DELETE, often used by RESTful applications to retrieve or modify data. Some RESTful applications add their own HTTP methods, such as WebDav, which adds PROFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, and UNLOCK.

REST is very intuitive for GET operations, and is a popular architectural choice for services on the public Internet. For example, Amazon and Google both provide RESTful interfaces to their APIs, and according to Jeff Barr, Amazon's chief web services evangelist, 85% of developers prefer Amazon's REST interfaces over their SOAP counterparts (Amazon provides both).

SOAP seems to be more easily adopted by the Enterprise, while REST is a natural fit for publicly facing Internet applications, in particular those applications where most operations are retrieving data (versus writing/posting/updating data). For example, XML results from a RESTful service seem more conducive to formatting with XSLT, simply because of the absence of the "extra" SOAP XML.

An RSS feed is a great example of a RESTful interface. I just point my favorite news reader to an RSS URI, and it's easily consumed. I can save the feed results to an XML file and easily convert it to XML using an XSL style sheet. REST is a data consumer friendly interface.


Which is Best?


Is one better than the other? I would say: hardly. That would be rather like choosing VB.Net over C#. Many developers may prefer one over the other, but you can get the job done using either tool.

On the flip side, I might recommend considering the desired feel of your application's API when choosing betwixt these two technology choices. Consider SOAP's object-orientedness vs. REST's web request based feel, and how each might impact adoption of your API.

Or, if you're using a technology like Microsoft's Windows Communication Foundation, which provides built-in support for both SOAP and REST, you won't have to choose at all.

But at least you'll know the difference.


Technorati Tags: ,,,

Monday, August 4, 2008

Twitterpated

I done did it. I went and got me an account on Twitter. I thought I'd give it a try and see what comes of it, what with all the hullabaloo about how wonderful it is. I suppose it was bound to happen sooner or later.

And so I submit to you this segment from Bambi, which I think sums up Twitter's Twitterpatedness.

Resistance is futile.

 

Technorati Tags: ,,

Thursday, July 31, 2008

IE 8 Seeking Beta Testers

But becoming a beta tester apparently requires writing an essay.

According to Allison Burnett's (Program Manager) latest post on the IE8 blog,

Currently the only way to directly file a bug with the IE Team is to be a part of the IE8 Technical Beta program on Microsoft Connect. Beta 2 is right around the corner and we are expanding our reach!  If you wish to be a part of making IE better by contributing great bug reports then please email us at IESO@microsoft.com and tell us a little about yourself including why you’d be a great beta tester.

An essay? You mean I have to sell myself as a worthy tester before I can submit a bug?

Judging by the comments she's getting, I'm not the only one that sees this as a mite odd...

Maybe more people would participate if:

a.) You allow users to download/view attachments so they can test bugs.

b.) You gave them feedback to indicate which bugs are being fixed, and when they are fixed.

c.) The current beta didn't have such a horrible auto-scrolling issue.

d.) MSFT made some sort of declaration that IE Feedback would actually be around after the IE8 RTM.  The fact that this was shut down after IE7 went RTM  ***LOST*** most of your loyal contributors.

...and...

I am not writing an essay on why I'd be a great tester.  You want/need more testers upload a current complied working build and the bug report tool in one place.  Let the web both see and use it.  Most of us have had terrible experiences so far with Beta 1 so perhaps it's time to release a Beta 2.

... and also...

Why, on earth, when other browser developers provide open and easy to use bug systems, would Microsoft limit itself in this way?

I have a bug in Webkit, five minutes can help me determine if someone had already reported the bug; no more than another five to submit the bug, with test case.

Mozilla created software to make it easy to search on, and submit bugs. Why, I bet even you all could use it.

Opera has a handy, dandy bug form that makes bug submission a snap.

And here is the IE team "If you email us and ask us really nice we may, just may, mind you, deign to let you actually tell us about that bug, which if left in the released product will haunt us until the end of time. If you don't ask nice, you can stuff your bug."

...and...

Dear Allison Burnett,

I've been a software engineer for 10 years and I'm taken back by why we need to provide reasons as to why we want to be great beta testers for a product that's on the decline in the web browser market. I expect this from a would be employer. I'm all for a better IE but this is not the best effort in gaining interest that Microsoft so dearly needs. You need to do more than just offer invitation to other beta programs.

...and so on. I think one commenter had Microsoft's thought process pegged on this one. That if you allow everyone to post bugs, and some of them don't get fixed, it might make them look bad.

And I'll just leave you with that.

Monday, July 28, 2008

LINQ Over Interwoven

Here at the large, International law firm in which I'm employed, we use Interwoven as our document management system (DMS) of choice. We've found it advantageous to expose a slice here and a slice there of Interwoven functionality via web service API's, which has become all the more easier using C# 3.0's new language improvements.

Allow me to demonstrate:

Extension Methods

If we want to use LINQ to enumerate over Interwoven's COM-based collections we need a way to easily convert them into an IEnumerable (or IQueryable). Extension method provide us with an elegant way of extending the Interwoven API so that it appears to give us IEnumerable access to its collections.

Here's a sample extension method for converting an IManage.IManFolders collection into an IEnumerable.

public static IEnumerable<IManage.IManFolder> ToIEnumerable(this IManage.IManFolders folders)
{
List<IManage.IManFolder> list = new List<IManFolder>(folders.Count);

foreach (IManFolder folder in folders)
{
list.Add(folder);
}

list.TrimExcess();

return list.AsEnumerable();
}


To really get a sense of how this makes our lives much easier as developers, let's just dive right into...


LINQ over XML


If you haven't played with LINQ over XML yet, allow me to demonstrate a smidgen of its power. This next block of code will recursively build a nested (and correctly indented) block of XML containing an Interwoven folder and all of it's child folders (using the extension method we created above).



public XElement GetFolderAsXElement(IManFolder folder)
{
return new XElement("IManFolder",
new XAttribute("Name", folder.Name),
new XAttribute("NrtId", folder.ObjectID),
new XAttribute("ObjectType", folder.ObjectType),
new XAttribute("FolderType", folder.ObjectType),
from IManFolder subFolder in folder.SubFolders.ToIEnumerable()
select GetFolderAsXElement(subFolder)
);
}


The beauty of the new .Net 3.5 XML classes (XElement, XDoc, XAttribute, et al), is in its readability. Anyone can take one look at that code and instantly understand the structure of the XML that's being created. And if you're paying close attention, you'll note that all the work being done in that function was succinctly described in only one statement!


I've heard many developers express concern over their coworkers and comrades going all rogue with these new features, particularly extension methods. But here, I think is an example where the new language features actually improve our code, and enable us to do what otherwise would have taken much longer.


Monday, June 16, 2008

No Developers for Windows Vista?

This CNET.com article (well, actually this report from Evans Data {login required}) implicates Windows Vista as not having a huge developer following. Which would be a little worrisome (for Microsoft) if true, as they have a history of providing fantastic developer support, yadda yadda.

But is it true?

First off, how would a developer write an application for Windows Vista? Unless you're writing device drivers or WPF-heavy applications (note that WPF also runs on XP after installing an update), I would find it difficult to write an application that didn't run equally well on Windows XP, or even Windows 2000.

I'm guessing (sorry, I don't have any charts and graphs eye candy) that most Windows-based LOB applications are developed against the .Net Framework, or are at least moving in that direction. DotNet applications Just-In-Time compile to run on the target platform (be it 32-bit or 64-bit, or even Linux or Mac OS), so it matters little what OS version you're running.

But if I could write a Vista targeted application, wouldn't that be a little stupid? Why would I limit my customer base to only Vista? Especially with all the bad press it's been getting lately.

I suspect Evans Data accurately surveyed the developer community, which accurately reported back that no, they're not writing applications for Windows Vista. But I submit that the results were a bit misconstrued.

But hey, maybe I'm way off base here, and totally clueless, so feel free to let me know in the comments!

 

Friday, June 13, 2008

System.Diagnostics.Stopwatch

I've noticed in a few forums here and there that, when gathering performance data, many developers often compare two System.DateTime objects (a before and an after object) to measure time-based performance stats. This works fine, but there's a much better way provided by the Stopwatch class in the System.Diagnostics namespace.

The Stopwatch class, believe it or not, works just like a real stopwatch. It has a method called Start(), a method called Stop(), and a few properties, Elapsed (which returns a TimeSpan) and EllapsedMilliseconds (which returns a long), that give you easy access to how long it took for your code to run. To start measuring performance you call the Start() method, and when your code is done doing what you want to measure, call Stop(). Then spit out the EllapsedMilliseconds somewhere convenient, maybe using a Tracepoint.

If your hardware and OS support a high-resolution performance counter, Stopwatch will use that, otherwise it measures time using the system timer. You can check if you high-res performance measurement is available using the IsHighResolution property.

Sample code is readily available in MSDN offline and online documentation.

Thursday, June 12, 2008

Supporting IE 8

Bill Gates announced during his Tech Ed keynote in Orlando last week that IE 8 Beta 2 would be released this August. You may already be aware that Microsoft has decided to release the final version of IE 8 with standards-compliant mode enabled, which will break many sites that assume that Internet Explorer is not a standards compliant browser.

To make it easy for sites to support IE 8 while retaining backward compatibility, Microsoft is introducing a few compatibility features.

A meta tag that will enable IE 7 mode on a per page basis (note that this is already available in Beta 1). This meta tag must be placed within a page's <HEAD> tags, thusly:

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />

Other browsers will of course ignore this tag.

If you want to enable IE 7 layout for an entire site, you can add a custom header (this will be available in Beta 2 this August):

X-UA-Compatible: IE=EmulateIE7

When IE 8 detects either the site header or the meta tag, it will then look at each document's DOCTYPE to determine whether to render the page in IE 7 Quirks or IE 7 Standards mode.

One migration strategy would be to add the site-wide EmulateIE7 header, and add the meta tag with content="IE8" to pages as they are modified to support IE 8's standards-compliant layout mode.

For more information on adding custom headers on various versions of IIS and Apache, notes about detecting different browser versions, and more, I refer you to the Internet Explorer blog on MSDN.

 

Technorati Tags: ,

Wednesday, June 11, 2008

Touching Windows 7

Bill Gates and Steve Ballmer gave a recent demo of the new Windows 7 user interface at the D6 executive conference this year. Or at least the touchy, feely bits. Check out the YouTube vid below for a look (warning: this video is eerily silent until the last few seconds, for some inexplicable reason).

Very nice and all, but this seems to violate the don't touch my monitor directive that many people (including myself) are quite passionate about. My  brother in particular is fanatical about keeping dirty fingers away from his monitor.

Which just makes sense. Who wants to write code through a thin layer of greasy smears? Or look at pictures, browse the web, play games, or pretty much anything?

So, maybe I just don't get it, but not sure this feature would see much mileage on my desktop.

Technorati Tags: