Manish, > Launchpad provides a WADL file describing the API for the web-service. I > wrote a WADL->C# converter called wadlsharp[1] . Actually with minor > modifications it can even create VB code but that is not the current > target. wadlsharp is just a library and I am yet to write it's > documentation. I created wadlsharp just to create the C# client code so > that customizing the generated C# code can as easy as possible. I have > released v0.1 of wadlsharp. Get the code from bzr[2] or download the > tarball[3]
First, I'm grateful that you're taking the time to write a .NET client for the web service. However, I think your current design will cause trouble later on for you and your users. Let me explain. I don't know any C#, so I don't understand what happens inside wadlsharp, but I believe your problems start there, with the generation of C# client code for later customization. I'm looking at LpClientProxy.cs in lpsharp, and it looks like it's the output of wadlsharp, or some wadlsharp-aided transformation of the WADL served by Launchpad on a specific date. I believe this design is a mistake, for three reasons. All three reasons are variants on a single reason: changes to the web service are not automatically reflected in the client. To see the changes, you must upgrade lpsharp. 1. Let's imagine that the Launchpad web service changes in a backwards-incompatible way. Scripts based on launchpadlib will break if they use the feature that changed, but launchpadlib itself will still function, and rewriting the launchpad-based script will fix the problem. Scripts that do not use the feature will still work correctly. >From what I can see about the way lpsharp works, lpsharp scripts that do not use the modified feature will still work. But, lpsharp scripts that do use the feature will break, and these scripts _cannot be fixed_ without upgrading lpsharp and _then_ rewriting the script. Because the lpsharp code was generated from an old version of the WADL, lpsharp has no way to find out what the new service looks like. In real life, we take great pains not to make backwards-incompatible changes to the web service. So this scenario is unlikely to happen. But I can't rule it out, especially since it can happen by accident. If it does happen by accident, your users (unlike launchpadlib users) won't be able to use a temporary hack to get their scripts working: that would require a new lpsharp release, and you don't want to do a new release just to deal with a temporary problem on the server side. 2. OK, now imagine that we add a backwards-compatible improvement to the web service. You don't really have to imagine this because we do it all the time. Looking at the service_root_json class in LpClientProxy.cs, I see members like: ... private string _pillars_link; private string _translation_import_queue_entries_collection_link; private string _bug_trackers_collection_link; private string _countries_collection_link; ... For (almost) any one of these links, there was a time in the past year when the web service did not publish that link. The same is true for (almost) all the named operations defined in LPClientProxy.cs as people_findPerson, etc. When we add anything new to the web service, existing installations of launchpadlib will pick up on it. Existing installations of lpslash will not. This is not a catastrophe--obviously scripts written before a feature was published will not break just because they use a lpslash that doesn't know about that feature. But it will be annoying to your users, and it will tie lpslash's upgrade schedule to Launchpad's. Your users will also be effectively unable to use the bleeding-edge 'devel' version of the web service, which changes on a regular basis and which may break its own backwards compatibility from day to day. Which brings me to... 3. Currently there are three versions of the Launchpad web service: "beta", "1.0" and "devel". Each publishes a slightly (or drastically) different WADL document. This is how we're able to make the strong promises we make about backwards compatibility (see #1). launchpadlib's Launchpad constructor takes a version name, and reads (from the server or from a cache) the appropriate WADL document at startup. If there are 5 versions of the web service, there can be up to 5 cached WADL documents on the user's hard drive, but there's only one copy of launchpadlib. Five pieces of data, one piece of code. By contrast, LpClientProxy.cs is derived from a specific version of the WADL as it was served on a specific date. If there are 5 versions of the web service, there need to be 5 versions of LpClientProxy.cs in a lpslash release. That's five similar pieces of code packaged with lpslash, which need to be updated whenever the web service is updated (once a month, in the limiting case). This isn't a showstopper (unless you consider the inability to access the new features of 'devel' a showstopper), but it violates Don't Repeat Yourself and it'll be annoying to create and distribute these regular releases. It will be even more annoying if you customize the generated code, which seems to be something you're considering. = Suggestions = OK, what is the alternative? I suggest that you think of lpsharp not as a C# "wrapper" for Launchpad's web service, but as a "client" or "browser" that happens to be scriptable through C#. That's kind of abstract, but I mean this: consider the WADL file as a piece of data to be consumed at runtime, rather than as a template for code generation. I appreciate that C# is a compiled language, and code generation seems like a better alternative in a compiled language. I don't know if it's possible to implement something like __getattr__() in C#--that's the fundamental technology underlying launchpadlib, and nobody wants to write launchpad['people'] or launchpad.get('people') instead of launchpad.people. If code generation really is the only way to make a reasonable C# client, I suggest you generate the code at runtime, keep it cached alongside the WADL file, and regenerate it whenever you start up lpslash and discover that the WADL has changed. But, I don't know if that's possible either! It might be too complicated or violate a C# security policy. To sum up: You will definitely be able to create a launchpadlib-like client using the architecture you have now. But the value of an lpslash installation will decline over time unless it's kept updated, whereas a launchpadlib installation maintains its value over time. Please let me know your thoughts, and feel free to ping me on IRC (leonardr) so we can discuss this in real time. Best, Leonard _______________________________________________ Mailing list: https://launchpad.net/~launchpad-dev Post to : launchpad-dev@lists.launchpad.net Unsubscribe : https://launchpad.net/~launchpad-dev More help : https://help.launchpad.net/ListHelp