Cmdlets vs. APIs

I’ve been working on a set of Powershell Cmdlets to fully replace the symstore.exe utility that is included with the Debugging Tools for Windows. (To be released as open source when I’m done.) When I think about writing Cmdlets, I tend to think that the best approach is to create an API and then wrap it in a Cmdlet implementation. That enables the best of both worlds–someone can write an application that uses the API, or people can interact with the Cmdlets via the command line or in an application hosting a Powershell runspace.

But I think I’ve been very wrong. A while back Jeffrey Snover posted a great “core dump” of cmdlets vs. APIs. He makes some good points, but even after reading it (back when he first posted it) I still thought that API + Cmdlet was the best approach. Experience has changed my mind. Here are, in my opinion, the most important points from his list (paraphrased).

Error handling. An API can throw exceptions, but a Cmdlet can have terminating and non-terminating errors. With Cmdlets users can easily control the behavior when a non-terminating error occurs as well as get access to the collection of troublemaker objects.

-WhatIf, -Confirm, and -Verbose support. There simply isn’t an easy way to have an API support a -WhatIf type of operation, while remaining a good API.

Pipelines and wildcards. Wildcard support needs to be implemented on a per-API basis, making it a time-consuming (and possibly difficult) task. Working with “pipelines” requires specific coding by the user of the API.

The common thread between those three points is that an API simply can’t provide those services independent of Powershell. You really can’t create an API and wrap it in a Cmdlet. (If you have a choice.) If my “Remove-Foo” Cmdlet simply wraps “foo.Delete()”, “foo.Delete()” can’t make use of advanced error handling, or conditional processing (ala “-WhatIf” or “-Confirm”), or pipeline or wildcard support.

Because applications can host a Powershell runspace, any argument for an API goes away. Your Cmdlets are an API that developers can write code against. The thing that still gets me about this, though, is the verbose code it requires to exercise a Cmdlet’s “API”. Apparently Powershell V2 is going to help simplify the runspace hosting story. Maybe that’s enough to knock the final leg out of my leaning towards an API? Once I finish my work, perhaps I’ll update the symstore SnapIn for V2 – in the meantime, I’d like to release them in a state that people could actually use them.

This entry was posted on Saturday, November 24th, 2007 at 10:53 pm and is filed under powershell, programming. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply