Thursday, October 15, 2015

Message based architectures empower polyglot developers

Demis Bellot recently responded to a question going into depth why a message based architecture approach works, I wanted to add this post to highlight how this approach is paying dividends for reuse across frameworks, languages and runtimes and empowering polyglot developers to build rich strongly typed clients in a simpler way.

A common story for ASP.NET developers

For the first few years of my professional programming career, I programmed almost exclusively in C#. Though I did JavaScript, it was introduced to me as not a 'serious` language and so I (incorrectly) treated it as such. I spent a significant amount of time learning the ins and outs of ASP.NET WebForms, memorise the life cycle of a web forms control, or how to deal with storing things in ViewState. I then threw away a lot of knowledge and started memorizing new concepts when moving to ASP.NET MVC.

During this time, my understanding of web development improved, I realized that these were just frameworks to help me get data off a web server and to the browser. With ASP.NET WebForms, you pretty much only had the choice to send everything, I found myself asking "But I just want to tell the client a small message to do something and it'll work out the rest.". I tried the use the hideously complex UpdatePanel and ScriptManager and whilst this improved the experience for the user, it was just painful to use from a developer's point of view. Next I used WCF WebGet and WebInvoke and various other ways. Even invoking these from JavaScript was difficult, other teams trying to use these services from another language like Java wasn't even considered an option at the time.I knew that in the end I was calling a HTTP server, but the interoperability of the web forms and WCF design was very annoying.

ASP.NET MVC made things easier, it was now at least plausible to write a client is another language and call methods on the controllers, but the client ended up having to wrap a one for one method of the local and remote call usually with matching signature. Though this wasn't overly difficult, it was very brittle.

A better way that continues to pay off

ServiceStack uses a different approach throughout its APIs. To create a web service in ServiceStack, you are required to create types that are your request and response data transfer objects (DTO). These simple objects without behaviour, that are required to declare for a service to work, might not seem like a huge deviation from other frameworks, but it's that requirement that makes all the difference. By forcing the developer to declare a simple DTO class of the message the service receives and responds with, it creates a contract between the server and client for that service call. As these classes are just transfer objects, i.e. everything they are is serializable into a message to be sent in various formats, it means they are able to be represented in any language that can accurately deserialize the message. The simpler the message, the more interoperable the functionality.

It's because of this architecture that ServiceStack can generate strongly typed DTOs in multiple languages accessible straight from the browser. The deep integration ServiceStack has provided into all the major IDEs, themselves in multiple languages was not only possible, but relatively straightforward because of this design. Service client generated from technologies like WSDL was highly complicated and commonly generated many thousands of lines of code to simple integrations. One generation I remember getting was after integrating with Cisco Unified Call Manager 8.5 AXL API using the WSDL code generator, I couldn't open the code file without Visual Studio almost crashing as it generates over 250,000 lines of code of C# (You'll need the AXLAPI.wsdl and associated XSDs to generate). To put that in relative terms, the entire Quake 3 engine is less than 400,000 lines of code, rendering, AI, networking, everything. The generated code from the WSDL is to make integration with a VOIP API easier.

To make the reuse of these DTOs simpler, ServiceStack provides a JsonServiceClient implementation to let developers have a clean, simple and familiar API when calling from different languages. These clients aren't hugely complex code bases hiding complexity either, for example the Java JsonServiceClient is less than 600 lines. And as another example of the power of this architecture, here is making the same call to get all Technologies from the demo application in 5 languages.

Even using languages where a service client hasn't already been written, the only requirements are a) you know the URL of the resource you want and b) you can serialize/deserialize the message into/from the language you're using from one of many formats ServiceStack supports.

I'll leave this post with another recent anecdote of this architecture empowering polyglot developers, within a day of the feature request for generating concrete, non-ambient TypeScript modules, this feature was incorporated and pushed out to the ServiceStack MyGet feed. This feature will now continue to add value for developers wanting a better experience when their ServiceStack services from a TypeScript client as all their APIs will now get this feature. If their API is central to their application they are building and selling, those advantages are now passed on to their customers as well.

Friday, October 9, 2015

Building an IntelliJ plugin using Gradle is easier than you might think

I recently had the problem of automating the build of an IntelliJ plugin so more of the process of updating the plugin could be automated.

I found a lengthy write up by Arjan Molenaar which I followed to originally get ServiceStackIDEA building on a new CI server. This use the `idea` gradle plugin to handle some of the IntelliJ project specifics. Although it works, it's quite verbose and requires the need to resolve the IDEA SDK zip, extract them temporarily, strip out dependencies so your plugin isn't huge amongst other things.

Even though I researched trying to solve this problem quite extensively and found quite a few artciles on how to do this, I missed the fact that Jetbrains have packaged all this required logic to get your IDEA plugin building for you in an easy to use gradle plugin of their own.

So the original 120 lines of quite fragile gradle gets turned into this.

So if you're trying to build an IntelliJ/IDEA plugin on a CI server, or even starting a new one, start with the gradle-intellij-plugin.