Micro-service languages: Typescript vs. Go

amit bezalel
8 min readFeb 10, 2017

--

JS is a good enough language in a pinch, but when you want to develop a large scale product with many programmers, it falls short. TypeScript gives you the structure you need for this. but what about GO? it seems to pop up everywhere we look lately…

My story

A couple of years ago when we started up the project, I had to choose a language for the server side of my POC, the options were NodeJS and Java, since we are talking about HP Software, not a small startup, there was a preference for Java which was considered more stable and mature, plus that we had the existing skill-set in the company for sharing manpower and code. After testing both, we ended up choosing NodeJS, since POCs have only one, all consuming huger, for development speed. In the life of a POC time to market is everything and NodeJS delivers extremely well in that department, we had our first sketch of a project out within two weeks.

When talking about languages I am actually also talking about the framework running it, and since most micro-service code is server side code, I’ll be talking about NodeJS and Typescript interchangeably.

TypeScript came later, and it was a natural progression to add structure to the project as more people joined us. It was a true save in regards to knowledge transfer, refactoring, and code readability, providing interfaces and type checking as well as go-to-definition and parameter order checks. Now GO is something new, and I am currently introducing into the project, which is for the most part, not intended to replace any of the currently written micro-services. I already have two modules written in GO and I am thinking of more.

Just about now, I see your eyebrows arching… you are asking me: “Amit, why do you need to go and complicate stuff, one new Language was not enough, you had to have more??”

So now everyone is using GO, right?

Actually not exactly, twitter just recently moved to NodeJS, Microsoft is using it in their Azure cloud, Netflix is in NodeJs and so are Wallmart, Pay-Pal, LinkedIn, Yahoo, Google, Uber and many more. It is correct that GO can be found in and around all the docker industry (including projects like Docker, Kubernetes, Prometheus monitoring, and more). It is also used in YouTube, Bitbucket, Facebook, netflix and more, go is considered So which is best? it’s not a simple as that, let’s dive into the details…

TypeScript

Typescript is a compiled language over JavaScript, which is used in NodeJS as well as in webUI development, on first encounter you see that it is very similar to what you already know so if you wrote JS, Java, C# or Cpp you will feel close to home. Although it’s JS-inherited single thread model sounds surprising at first, it is actually much more parallel than Java when working with IO, since all IO tasks are handled by IO threads in the OS, your code is only responsible for facilitating the needed connections and dispatching tasks to disk or network operations. You do, however, need to steer clear of running any CPU bound operation in your code, so image processing / heavy data restructuring / etc. should be done in other processes.

Asynchronous code writing takes some time to master (if you are not coming from JS already), but it does help performance, and once you got used to working with promises, it seems easy as pie.

// define a class
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
// instantiate the class
let greeter = new Greeter("world");
let button = document.createElement('button');
button.textContent = "Say Hello";
button.onclick = function() {
// call a member function
alert(greeter.greet());
}
document.body.appendChild(button);

Tooling: TypeScript has two good IDEs to choose from VsCode which is a free OpenSource tool from Microsoft which is also cross-platform and IntelliJ 2016 or 2017, previous versions were not that good for TS, also VisualStudio 2015 was way too heavy to be of any real use. Debugging and remote debugging (attaching to process etc.) is easy enough, and when getting to the release stages of the project, you will see that there are also some nice tools around memory and CPU profiling for performance optimizations.

Typescript is: Full-stack (can be used in UI and in server side), Fast to adopt (familiar syntax, gradually convert JS projects) and has a huge repository of community driven modules (npm). In the same time it requires you to install NodeJS on the target machine, can’t hold CPU intensive tasks, and is completely open on disk, this means that it is optimal for most cloud-native apps use cases, but for some special micro-services and for most client installed components it may not be the best solution.

GO

Go is a fairly new language, first publicly announced in 2009, reaching v1.0 only in 2012, it’s growth rate is moderate in comparison to NodeJS. There are several differences that set it apart from all the most popular languages currently in the market:

  • GO is a modern compiled language (at last!), the programming language market in the past decade has been dominated by semi-compiled languages and scripts, these gained traction since they are easier to use cross-platform. But such languages also produce an end product that is easy to hack (when distributed), and hard to optimize (no JIT engine can beat a CPU optimized native binary). Go gives you a fully featured framework for a 1.7MB overhead in your executable, that includes all the familiar String handling / OS / IO / Server / serialization & parsing commands, plus a lightening fast garbage collection engine, which only pauses the process for a few milliseconds at a time. It can also cross compile to other OS and CPU architecture permutations, without keeping these systems around as it creates fully functional executables for all target systems on a single build machine (think of the DevOps benefits compared to Cpp builds). Compilation is very fast, and even a large scale project will compile in seconds .
  • GO has a built in parallel framework from day one, which is modeled as a pipeline flow network. This model includes groups of same-code parallel workers (go routines), that are interconnected by producer-consumer queues (channels) and is very similar to C# TPL DataFlow architecture, or if you will, to an in-process micro-services architecture. It also hides all the internal workings of threads including thread pooling and all thread-per-core dilemmas, with some fancy heuristics.

Adopting Go isn’t done without difficulty, it has an opinionated model regarding the way projects should be laid out on disk, and how dependencies should be kept and managed (gopath, packages), it’s internal syntax is built for compiler optimization, and is less object oriented than the current languages, which isn’t necessarily a bad thing. Structs only hold data, functions are attached to them later, in any time from any code (so, no sealed classes). An unused parameter is a compiler error and unused imports are deleted by the format utility, (which is strange if you are like me, used to pressing “format code” after every second key stroke), and there are no end-of-line semicolons.

It is also worth mentioning that the existence of pointers in Go doesn’t complicate the usage since Go is lenient here, allowing the same “.” operator for both (not like Cpp that requires “->” for members under pointers, there is also an automatic conversion between pointers and values in function calls.

Finally, as with all cross-OS programming, using native (cpp) components is ill advised, as it is hard to get cpp to compile when moving between Windows and Unix based systems (Max/Linux), this is further complicated by Go’s friendliness towards integration with natively compiled libraries that results in many prominent libraries that utilize existing open source cpp assets. (I’m looking at you Git2Go).

// define a struct
type rect struct {
width, height int
}
// add a method to the struct
func (r *rect) area() int {
return r.width * r.height
}
// Methods can be defined for either pointer or value
// receiver types. Here’s an example of a value receiver.
func (r rect) perim() int {
return 2*r.width + 2*r.height
}
func main() {
r := rect{width: 10, height: 5}
//call a method on the struct.(see pointers & values in definition)
fmt.Println(“area: “, r.area())
fmt.Println(“perim:”, r.perim())
//doesn't matter if you call it on a pointer
rp := &r
fmt.Println("area: ", rp.area())
}

When looking at the Go marketplace, the first thing that you notice is that in contrast to npm & npmsearch, there are no really good, organized repositories with module ratings and versatile search engines. you would need to search the forums and play around by yourself to find the best pick. Package storage is distributed, each package downloadable from its owner’s git of choice, which sounds like a neat trick but can result in missing packages / versions down the line, this mechanism also doesn’t easily lend itself to in-company caching like nexus does for npm.

Tooling: For a good Go IDE you can again find VsCode and IntelliJ, both with their respective Go plugins, to be my two recommendations, but there are not too many others IDEs to test here, when not including “text editor on steroids” applications like atom and sublime.

Another issue i have with about Go, is its debugger, the delve debugger is the only debugger for go, and it is yet to gain maturity and release it’s v1.0, i have worked with 0.10 (which had several annoying bugs) and now with 0.12, and it feels that is has just now become completely usable, and there is yet some way to go for real maturity.

Summary:

To sum up all that was written here, let’s have a nice comparison table for all the features:

both languages are cross-platform, fast to compile and have a vibrant community, however, they are different in their orientation. One may even say they are complimentary, so by using NodeTS for most of your services you can gear up fast, and have access to all the npm modules, easy JSON parsing and loose typing that makes server writing extremely easy, and by using Go for implementing client side distributable components, image thumbnailing, video encoding, and all complex data conversions you can create a system that is best suited for the job. All of which is enabled by The polyglot environment created by using the micro-services architecture.

--

--

amit bezalel

After 17 years developing software, Coding is still a passion of mine, a hands-on SaaS cloud architect working in TS and GO & learning something new everyday.