Musings

Advanced Javascript: Typescript In Action

Apr 6, 2017. | By: Juan Carlos Cancela

Description

During a project I was working on a couple of months ago, I got the opportunity to work for my very first time with Typescript.

Typescript is a language that “basically formalizes a static type system that describes JavaScript’s dynamic types, but it describes them at development time”, as Anders Hejlsberg -creator of C# and Typescript itself- have said.

Typescript in a nutshell

Its Javascript

  • Superset of Javascript that compiles to JS
  • Transpilable to plain Javascript
  • Interoperates with existing code

…but better!

  • Type annotations
  • Interfaces
  • Classes
  • Generics
  • Enums
  • Async/Await
  • Decorators
  • …more

Lets dig a bit more into some these points:

  • The fundamental aspect to understand about Typescript is the fact that it is a superset of Javascript. The direct implication of this is that any current, plain javascript application is, indeed, a Typescript application. You dont need to change a single line of your application code to start using it, right away.

  • Secondly, Typescript source code is transpilable to plain Javascript, that is, through a bundling tool like Browserify or Webpack -and using the appropiate loader- your Typescript source is transformed to javascript that any javascript engine can execute.

  • One direct implication from previous points is that your newly Typescript code can easily interact with your existing Javascript one. Typescript starts as Javascript, and finishes as Javascript as well

Typescript features

As mentioned before, Typescript provides Javascript with a powerful typing system. Thanks to that, it is possible to use features available on other languages, in Javascript.

Let’s review some of these features and direct examples where its useful:

Interfaces

An interface can be thought a contract that specifies inputs and outputs of a given component. That is, the operations that we can execute on any component that implements such interface. Consider following example: We have a Repository interface that has four operations (create, read, delete, update) we could define an interface as follows:

interface Repository {
    create(instance);
    delete(id);
    read(id);
    update(id, instance);
}

Then, we might have a class that implements Repository interface, like this:

class MySqlRepository implements Repository {
    create(instance){ /...(implementation)/ };
    delete(id) { /...(implementation)/ };
    read(id) { /...(implementation)/ };
    update(id, instance) { /...(implementation)/};
}

Now consider this: Suppose we have an application that uses this MySqlRepository implementation to connect to a MySql instance. For whathever reason, we need to change from MySql to PostgresSQL. Having interfaces we could implement a new PostgresSqlRepository class like this:

class PostgresSqlRepository implements Repository {
    create(instance){ /...(implementation)/ };
    delete(id) { /...(implementation)/ };
    read(id) { /...(implementation)/ };
    update(id, instance) { /...(implementation)/};
}

that implements Repository interface, and then, safely switch between available implementations. So, an interface is a mechanism to enforce a particular piece of code to provide a well defined list of operations that needs to be implemented.

Type Inference

Typescript compiler provides a powerful type inference implementation, that allows compiler to infer lots of information about our Javascript code. Consider this case:

function add16(val){
    return 16 + val;
}
var v = add16("val"); // TS type inference mechanism will warn us that we are adding a number to a string

Typescript compiler’s type inference mechanism is so powerful that makes sense to use it even if we are now going to code a single line of Typescript.

Typescript infers this using four simple rules:

Inference by Assignment:

Consider following example:

type Adder = (a: number, b: number) => number;
let foo: Adder = (a, b) => a + b;

let foo2: Adder = (a, b) => {
    a = "hello";
    return a + b; //Error cannot assign string to number
}

As it can be seen, a is declared as a number, but then a string is assigned. Typescript will recognize this pattern, and let us know that looks like theres an error in code, since a variable of type number is being assigned with an string.

Inference by Variable Definition:

let foo = 123;
let bar = "Hello";
foo = bar; //Error: cannot assign string to number

in this case, foo is initially assigned value 123, then infers its a number, and bar with an string. When we try to assifn foo to bar, Typescript will let us know we are trying to assign a string to a number.

Inference by Return:

Suppose we have a function addNumbers as follows:

function addNumbers(a: number, b: number){
    return a + b;
}

var a = "";
a = addNumbers(1,2); // Error cannot assign a number to a string

Again, Typescript type inference mechanism will let us know that based on the return type of the addNumbers function, theres an error, since we are trying to assign it to a string value (a).

Inference by Structure:

Finally, Typescrip is able to infer type of variables using structure:

let foo = {
    a: 1,
    b: 2
}

foo.a = "hello"; //Cannot assign a string to a number

Property a of foo object was initially set to 1, then Typescript will output an error when we try to assign an string to it.

Generics

Following Repository interface example, we can see that read function can return anything:

interface Repository {
    create(instance);
    delete(id);
    read(id);
    update(id, instance);
}

Ideally, we would like to define the return type of the read function with a provided value. Kind of a parameter to the interface / class definition itself. One way to do it could be to set the return of read to a particular type, in example:

interface PersonRepository {
    create(instance);
    delete(id);
    read(id):Person;
    update(id, instance);
}

Now, Typescript will check that the return type of read needs to be an instance of Person class. So, we will probably have an implementation as follows:

class PersonPostgresSqlRepository implements PersonRepository {
    create(instance){ /...(implementation)/ };
    delete(id) { /...(implementation)/ };
    read(id): Person { /...(implementation)/ };
    update(id, instance) { /...(implementation)/};
}

PersonPostgresSqlRepository is a final class that implemented PersonRepository, and thus, it enforces read function to return an object of type Person. One problem we will find with this approach is that we could eventually be duplicating lot of code. What if we have hundreds of objects like Person in our app? For such cases, generics are a handy abstraction that enables parametrization of interfaces and classes. Consider following Reposutory interface using generics:

interface Repository<T> {
    create(instance);
    delete(id);
    read(id):T;
    update(id, instance);
}

Now, read function returns type T, which we are able to specify. Now, we could have something like this:

class PostgresSqlRepository<T> implements Repository<T> {
    create(instance){ /...(implementation)/ };
    delete(id) { /...(implementation)/ };
    read(id): T { /...(implementation)/ };
    update(id, instance) { /...(implementation)/};
}

let personRepository = new PostgresSqlRepository<Person>();
let departmentRrepository = new PostgresSqlRepository<Department>();
...

As you can see, you can think of generics as type placeholders.

Code Examples

I have created a clean, Express Hello World app that you can use for any Typescript project. In this project, Webpack and Typescript are properly configured to transpile code to ES5 target: repo

Also, theres a Pull Request with some example refactors to take a look: refactors

[Permalink]

Toy Robot: Test your JS maze solving algorithms

Apr 4, 2016. | By: Juan Carlos Cancela

Description

Toy Robot is a tiny JS project I have developed, that basically takes an input file with a sequence of movements, and tries to reach the exit of a labyrinth.

Installing Toy Robot

On application root path, run following command to download application dependencies:

npm install

Starting application

npm start <FILE_PATH>

Executing application unit tests

npm test

Checking application code coverage

npm run coverage

Running provided examples and additional data sets

  • To run Example A (described in PROBLEM.md), execute:

$ npm run example_a

  • To run Example B (described in PROBLEM.md), execute:

$ npm run example_b

  • To run Example C (described in PROBLEM.md), execute:

$ npm run example_c

  • To run additional set A, execute:

$ npm run additional_a

  • To run additional set B, execute:

$ npm run additional_b

Code

Feel free to fork / clone project and test your own algorithms with it: repo

[Permalink]

Ecmascript 6: the fun bits (part 1)

Jan 4, 2016. | By: Juan Carlos Cancela

Ecmascript has become an official standard during last months, so well worth to revisit some of the new features defined in the new spec.

Screenshot

var vs let

In ES5/6, using var for variable declarations trigger an internal javascript engine process that “hoists” (move variable to the top of the declaration) variables:

// Using var, variable declaration is moved to the top of the function
// declaraction, no matter where is initially declared.

function dosth(value){
  if(value){
    var test;
    console.log("value");
  }

  // Intituively you may think test variable does not exist if value is not true,
  // but due to variable hoisting, thats not true.
  console.log("finished execution");
}

// This is how Javascript changes your function under the hood
function dosth_hoisted(value){
  var test;

  if(value){
     console.log("value");
  }

  console.log("finished execution");
}

With ES6, using let, it is possible to declare variables using let, allowing real block scope declarations. Check this example:

// Variables initialized with let follow the traditional approach of defining
// block level declarations (so, no variable hoisting, so, what you usually
// se in traditional Java like languages)
function dosth_let(){
  if(value){
    let test;
    console.log("value");
  }

  // If value is not evaluated as true, then test value wont exist.
  console.log("finished execution");
}

const to freeze keys of an object (but not values!)

const under ES6 is a block scope declaration, and furthermore, it allows freezing an object key set (but not its values). See this example:

// Defining a const computer object, it wont be possible to add new keys to
// computer object.
const computer = {
  brand: "Apple",
  model: "II"
}

// valid!
computer.brand = "Microsoft";

// throw error
computer.price = "1564";

String interpolation

Another powerful feature in ES6 is string substitution. Let’s see an example:

// Prints numbers from 0 to 9
var countNumbers  = function(){
  for(var i = 0; i < 10; i++){
    console.log(`${i}`)
  }
}

As you can see, using backticks and ${variable}, you can interpolate strings with calculated values.

Default Parameters for function

Some subtle improvements were added to function manipulation in ES6. In particular, let’s see how default values are handled:

// If protocol parameter is not passed, it defaults to https
function create_url(protocol = "https", domain){
  return `${protocol}://${domain}`;
}

Even better, it is possible to send functions as default values. Check this example:

// If date is not provided, defaults to current date
function print_date(date = getCurrentDate()){
  console.log(d);
}

function getCurrentDate(){
  return new Date();
}

More in github :)

All code snippets are published in repo. ES6 is huge, and there are lots of new, powerful features. I’ll be periodically updating repo with new examples. In the future, I’ll be writing specific articles talking about some of the most complex features in ES6, in example, Generators and Proxies. Enjoy!

[Permalink]

Code for fun: Australian Tax Calculator!

Dec 12, 2015. | By: Juan Carlos Cancela

So a time ago I was required to do a simple test. Objective was to create an app to generate australian employee payslip. In particular, given an annual salary, the super rate and initial period date, it is required to return the gross and net income, super as well as income tax.

Screenshot

CLI

Originally, app was an http service, but since it would eventually be useful for someone, I refactored it so it can be used in a much more simpler fashion as a command line tool. So, if you want to know how much government will grab from your money, just execute something like

$ austax ANNUAL_SALARY SUPER_RATE INITIAL_PERIOD

In example:

$ austax 100000 0.4 12/12/12

####Code

I have published solution and tests in this repo, as well as a couple of tests for it. Enjoy!

[Permalink]

Introducing Dromedary, a minimalistic, lightweight API decorator

Oct 1, 2015. | By: Juan Carlos Cancela

A time ago, during a side project I worked for, I was faced with the need to integrate a couple of services. All in all, it was needed to consume some HTTP services, apply some transformations and establish a clear routing through them. Since client was already using a Java technology stack, we end up using Apache Camel to get the job done. Anyway, I was particularly interested to see if it could be a way to achieve not so complex integrations using non Java technologies. In particular, I wanted to try if using Express Middleware, plus some configuration-driven architecture could eventually enable a potential generic solution for such use cases.

####10000 feet view

This is more or less the way I imagine it

Screenshot

So the case is an existing HTTP service (maybe I wouldn’t limit wrapped application to be an HTTP service, who knows?) that is directly consumed by some clients. Owner of HTTP service wants to decorate its existing API adding things like security, third party API consumption, or applying certain modifications to incoming requests. Dromedary would act as a proxy service that will handle every single request to the API, and apply an ordered list of configurable plugins before letting request reach existing service. Additionally, once HTTP response comes back from it, it would apply any plugin configured to be executed after service invocation.

####Implementation Wish list

Next, lets craft a wish list of characteristics that could be made in order to make library implementation simpler and somehow different compared to other options. So…

  • Solution must be configuration driven: Ideally, through a config file it would be possible to declare and configure the plugins that compose the gateway.
  • Plugin based architecture: Library must provide a way to consume plugins that can accomplish different features. In example, it would exist a plugin that can be declared through the configuration file, that enables transforming some values in an HTTP response.
  • Lets be clear again about first wish: Integration is a config file. Not a Node app, a Javascript file, or something else. Just a plain file that can be pass to a command line tool that takes care of correctly process it.
  • This config files would be composable. So, a it would be able to consume another config file. Ideally, a much complex integration could be split in several config files, each of them abstracting integration details.

Screenshot

####Dromedary alpha version

Taking as input the use cases plus implementation wishes detailed above, I have developed a prototype of the library to start trying and iterating through it. Library is registered in NPM registry here, and code is versioned here.

####Next On second part (soon!) I’ll take a closer look at proof of concept implementation, and show some real cases where it could actually be quite useful.

[Permalink]

Code for fun: the value of a word!

Jun 12, 2015. | By: Juan Carlos Cancela

Last Friday, I was checking Facebook, and found an ad from a site named “hackealo.co”. Out of curiosity, went there, and was presented with a fun coding challenge:

####Problem:

The “value” of a word is the sum of the value of each of its characters. The “value” of a character is the product of the position of the character in the work by the position in the alphabet. IE, the value of “abc” is (1 x 1) + (2 x 3) + (3 x 2)

What is the value of permutations of word “kTBXJJU”?

####Resolution

   
   /**
    * Based on ASCII position, returns the value of a character, 
    * taking in consideration the offset.
    * @param character character to which value will be calculated
    * @returns {number} value of character
    */
   function characterValue(position, character) {
       var OFFSET_ASCII = 96;
       return (character.toLowerCase().charCodeAt(0) - OFFSET_ASCII) * 
       (position + 1);
   }
   
   /**
    * Generates the n combinations of the given word
    * @param word word
    * @returns {Array} Array with combinations of word
    */
   function generatePermutations(word) {
       var permutations = [];
   
       function permute(arr, memo) {
           var current;
           var memo = memo || [];
   
           for (var i = 0; i < arr.length; i++) {
               current = arr.splice(i, 1);
               if (arr.length === 0) {
                   permutations.push(memo.concat(current));
               }
               permute(arr.slice(), memo.concat(current));
               arr.splice(i, 0, current[0]);
           }
   
           return permutations;
       }
   
       return permute(word);
   }
   
   function wordValue(word) {
       if (!word) return 0;
       var wordValue = 0;
       var wordPermutations = generatePermutations(word.split(""));
       wordPermutations.forEach(function (combination) {
           for (var i = 0; i < combination.length; i++) {
               wordValue += characterValue(i, combination[i]);
           }
       });
       return wordValue;
   }
   
   /**
    * Public Interface
    * @type 
    */
   module.exports = {
       wordValue: wordValue
   };
 

####Code

I have published solution and tests in this repo in algorithms/extras, as well as a couple of tests for it.

[Permalink]

Using NodeJS for command line tools

Jun 10, 2015. | By: Juan Carlos Cancela

Since arrival of NodeJS, using Javascript to create command line tools (CLT) as a replacement of traditional bash scripting is a reasonable option.

####Creating a simple node app to be used as CLT

Let’s create a simple CLT app that to send mails using command line:

  • Create a directory ´cltool´
  • Run ´npm init´ to create a package.json file
  • Replace content of package.json with following data:
   {
     "name": "heyhey",
     "version": "1.0.0",
     "description": "sends a mail. Usage: 'heyhey <mail@mail.com> <subject> <message>'",
     "scripts": {
       "test": "echo \"Error: no test specified\" && exit 1"
     },
     "author": "Juan Carlos Cancela",
     "license": "MIT",
     "preferGlobal": true,
     "bin": {
       "heyhey": "heyhey.js"
     },
     "dependencies": {
       "nodemailer": "*"
     }
   }
 

In name, it is defined the name of the command line tool

In bin, it is established the file to be executed when command is invoked

  • Create a file heyhey.js
   #! /usr/bin/env node

   var userArgs = process.argv.splice(2);
   var to = userArgs[0];
   var subject = userArgs[1];
   var message = userArgs[2];

   var mailOptions = { from: 'cancela.juancarlos@gmail.com', to: to, subject: subject, text: message, html: '<b>'+message+'</b>'};
   var transporter = require('nodemailer').createTransport({ service: 'Gmail', auth: { user: 'cancela.juancarlos@gmail.com', pass: 'XXXXX'}});

   transporter.sendMail(mailOptions, function(error, info){
      error ? console.log(error) : console.log('Message sent: ' + info.response);}
   );
 

In 1 it is defined node to run the script

In 2 user provided arguments are obtained

In 3 is created the command to be executed (using user provided args)

In 4 we execute the given command

  • Finally, execute npm link to create a symlink to the command line application

Using CLT

From command line, try executing the recently created command; in example; ´heyhey “mail@gmail.com” “hi!” “hey how are you!”´

Example code

Code used in this article is available in this repo

[Permalink]

Slicing technologies per method

Apr 25, 2014. | By: Juan Carlos Cancela

During a project I have worked for, as dev team we were confronted with the need to scale an already existing API, trying to minimize changes to its core. Current state could be summarized as follows:

  • API was developed using a typical Java - Spring - Hibernate stack
  • MongoDB was used as persistence store
  • Service was slow due to the way serialization/deserialization of objects was implemented

As mentioned before, modifying core to improve serialization/deserialization was not an option.

After talking with product owner, we realized that due to the nature of required feature, we could expect way more readings, but no -or minimal- growth on non safe, non idempotent operations.

We could safely assert that we needed to scale API in order to support newly large amount of GET operations.

####Scaling GET

Actually, read operations were quite simple to handle: Just creating a dynamic predicate, getting matching documents from MongoDB, and sending them back on response. Problem was that the already mentioned serialization/deserialization process was involved in current service implementation.

Screenshot

To tackle that, we initially tried to find a way to overpass ser/des calls, but due to the way service was implemented, that was not possible.

####Routing GET to a new service

So finally we decided to implement a new service, exclusive for GET calls to API. To do that, we implemented a service using NodeJS. Since NodeJS is Javascript and MongoDB persists docs as BSON, there was no need of additional ser/des process. We just needed to adjust reverse proxy in order to correctly route API calls to the proper implementation. In this way, we were able to:

  • Successfully scale service as expected
  • Do not change current legacy service, as requested
  • All changes were 100% transparent for API users

Screenshot

####Generalizing concept

After this experience, I found that in some scenarios (as the one described in this post) picking different technologies per API method could make sense. In example, using a class based, compiled language as Java could be eventually more convenient in some routes of API, and lightweight, easier to implement Javascript code could be used on others.

[Permalink]

About

Motivated, action-oriented technology enthusiast with experience on multiple industries designing cutting-edge Web API-centric applications.

Social Links

Location

Buenos Aires, Argentina