Tuesday, September 22, 2015

ReactJS JSX gives us HTML in JavaScript

What I consider the main difference between ReactJS and its JSX syntax when compared to the other frameworks like AngularJS, EmberJS, and BackboneJS is that JSX is HTML in JavaScript. The others have JavaScript in the HTML.

HTML-in-Code instead of Code-in-HTML.

Here's a simple example:




React's JSX:

myCollection.map( (item) => {

  return render (

    <div>{item}</div> 

  );

});


AngularJS:

<div ng-repeat="item in myCollection">

  <div>{{item}}</div>

</div>

One of the things that we continuously struggle with is the ability to program markup. To do this we've been adding language to the markup.

JSX stands that paradigm on its head and adds the markup to the language.

As a developer I enjoy writing code more than writing markup. JSX means that I don't have to jump-out-of the markup to make things happen to it. The markup is encapsulated inside the logic that controls the flow of the application.

With AngularJS I'm consciously wiring language and markup together.

AngularJS appeals to the designer in me while JSX appeals to the developer in me.

I'm not against AngularJS or the other frameworks. I enjoy writing code and solving hard problems. I also hated the sight of JSX when I first saw it and before I wrote my first project in it. It didn't seem right to pollute JavaScript with markup.

For me the AHA moment was the productivity I felt that React gave me by keeping me in my area of expertise: JavaScript. I'm good at HTML and CSS. I'm an expert at JavaScript. More productivity happens in your area of expertise.

Long live ReactJS.
Long live AngularJS.



Monday, September 21, 2015

Thousands of Lint Warnings and Errors


You add linting to your project and suddenly you're faced with thousands of lint warnings and errors. What's the point? You're never going spend those hours upon hours fixing all of this. Or are you?

I use ESLint for linting on JavaScript projects.

If I start a project I add a set of linting rules (in the .eslintrc file) and an automated way of running them with tests or checkins and the project remains lint free. That's easy.

Adding lint rules to an established project is tough, especially if you have a set of predefined rules you want to use and they are generating more warnings and errors than you can address.

The best way, I've found, for adding a linter in this case is to:
  1. Add all your lint rules using the .eslintrc file.
  2. Run the linter and then disable each rule that is generating a warning or error until there are no more warnings or errors.
Now go back to coding on your project and when you hit the wall turn to enabling a lint rule as your stress relief.

We all have times when things are not going well in the code base and we need to take a break to refresh, regroup and take another approach at what we're doing.

These breaks are perfect times to see if we can switch one of those disabled lint rules to a warning or error level and improve the quality of the code. It's also a great opportunity to scan over the entire code-base and re-familiarize yourself with parts that you'd forgotten about or parts that might be dead and can be removed.

Saturday, September 19, 2015

Consuming a JSON REST result in C# .NET


Yesterday I wrote about an Simple API server for IP Address Information Lookup that I had created in Node.js. This server produces a JSON result that looks like this for IP address 8.8.8.8:

{
   "city":{
      "geoname_id":5375480,
      "names":{
         "en":"Mountain View",
         ...
      }
   },
   "continent":{
      "code":"NA",
      "geoname_id":6255149,
      "names":{
         "de":"Nordamerika",
         "en":"North America",
         ...
      }
   },
   "country":{
      "geoname_id":6252001,
      "iso_code":"US",
      "names":{
         "en":"United States",
         ...
      }
   },
   "location":{
      "latitude":37.386,
      "longitude":-122.0838,
      "metro_code":807,
      "time_zone":"America/Los_Angeles"
   },
   "postal":{
      "code":"94040"
   },
   "registered_country":{
      "geoname_id":6252001,
      "iso_code":"US",
      "names":{
         "en":"United States",
         ...
      }
   },
   "subdivisions":[
      {
         "geoname_id":5332921,
         "iso_code":"CA",
         "names":{
            "en":"California",
            ...
         }
      }
   ]
}

I wanted to consume this end-point in a C# application. A quick search for solutions on how to consume a JSON result from a REST service showed some very complicated ways of doing this. This is a simple solution that I came up with:

// A simple C# class to get the details of an IP address
public class IpApi
{
    public IPInfo GetIPInfo(string ip)
    {
        // Create the URL for the REST endpoint
        string url = "http://localhost:3000/ip/" + ip;
        // Create a .Net WebClient object
        WebClient wc = new WebClient();
        // Get the string result from the REST endpoint
        string json = wc.DownloadString(url);
        // Use Newtonsoft JsonConvert class and its static
        // DeserializeObject method to parse the string into
        // a .Net object
        return JsonConvert.DeserializeObject<IPInfo>(json);
    }
}
// The following classes create the JSON object graph hierarchy
// in static classes. It's a bit tedious looking at the JSON
// object and typing these out. I'd imagine that if you're 
// doing this a lot you could write a tool to generate these
// classes using the JSON as input. Or perhaps there's already
// a tool that does this?
public class Names
{
    // I didn't need the pt-BR and zh-CN key/values from the
    // names so I didn't bother looking up how JsonCovert maps
    // those. 
    public string de, en, fr, ja, ru;
}
public class City
{
    public Names names;
    public int geoname_id;
}
public class Continent
{
    public string code;
    public Names names;
    public int geoname_id;
}
public class Country
{
    public string iso_code;
    public Names names;
    public int geoname_id;
}
public class Location
{
    public decimal latitude;
    public decimal longitude;
    public int metro_code;
    public string time_zone;
}
public class Postal
{
    public string code;
}

public class IPInfo
{
    public City city;
    public Continent continent;
    public Country country;
    public Location location;
    public Postal postal;
    public Country registered_country;
    public Country[] subdivisions;
}



Friday, September 18, 2015

Simple API server for IP Address Information Lookup


I find that I often have the need, in a web application, to lookup information about an IP address that a request comes from.

To serve this purpose I created IPAPI (GitHub), a simple server providing a single API endpoint that returns information about an IP address.

(You should try the server just because the name is a palindrome. Imagine the awe and respect you'll get when you say "I ran a Palindrome API server today.")

The server runs on Node.js and uses the GeoLite2 database from MaxMind.

You can install and run the server with:

git clone [email protected]:guyellis/ipapi.git
npm install
node index.js

or

npm install ipapi
node node_modules/ipapi/index.js

The server will download and unzip the IP database if it's not found locally.

Using the server is as simple as having your client call http://<your-domain/ip/<x.x.x.x> and getting back JSON with information about the IP.

There are plenty of improvements that can made to this simple server. Pull Requests gladly accepted.

Thursday, September 17, 2015

Improving Security in Node.js



A collection of tips and ideas to improve the security of a Node.js application.

Don't let your app identify itself as a Node.js application

In the response header you might have:
X-Powered-By: Express
Set-Cookie: connect.sid: sJbhAJcKt1JVuCRZ5HwpYMhFBAKaXm0

The first item identifies that your application is using Express.js which identifies Node. The second in a similar manner identifies the Connect middleware for session management, again a Node module.

The fixes for these are very simple. To suppress the X-Powered-By header key/value you should do this:

app = express();
app.disable('x-powered-by');


For the connect.sid identifier you can change the default name by using the "key" key in the initialization object:

app.use(session({
  key: '<customize me>',
  ...



Wednesday, September 16, 2015

No Website Needed


I have a friend who's an architect. He does bespoke designs for shops and houses. He's never had a website and he says that's one of his unique-selling-points (USP) when talking to a customer.

Apparently the conversation goes something like this:

Customer: "I searched the web and I couldn't find your website or anything else about you."
Architect: "The only reason that we're talking now is because someone, probably an existing client, recommended me to you. I only do work through referrals and I find that I have more work than I can cope with."

In his response he's implying that he's that good that he doesn't have to advertise. According to him that's a very powerful sales pitch during the initial consultation with a future client. A website, he feels, would not allow him to use that line in closing a sale.

Tuesday, September 15, 2015

Moving your Team and Project to ES6

How do you safely move your team to using ES6?



1. Convince the team/boss/stakeholders that it's time to move to ES6


The points in this article might help.

2. Decide what you're going to use


Are you going to use a transpiler like Babel or a shim? If using Node.js are you going to use the --harmony flag? There are plenty of articles that discuss this.

3. Start using ES6


Most teams will have at least one person who wants to use the new syntax. This is how these developers should introduce ES6 to the rest of the team.

Training? That's one way. Another is to cross-train each other on a code base that you're already working on.

Let's say that you wrote some ES5 code like this:

handleChange(name, e) {
  var change = {};
  change[name] = e.target.value;
  this.setState(change);
}

and you decided that you'd rather use ES6 syntax like this:

handleChange(name, e) {
  var change = {
    [name]: e.target.value;
  }
  this.setState(change);
}

The better way to use the ES6 syntax is to tag it with the name of the new feature like this:

handleChange(name, e) {
  var change = {
    // ES6: Destructuring, computed property keys
    [name]: e.target.value;
  }
  this.setState(change);
}

A developer looking at the ES6 comment should be able to copy/paste the text into a search engine and find a reasonable list of articles that deal with the feature.

4. Teach in the Pull Request Review


Now when you do a Pull Request on your changes message the rest of the team that there are labeled ES6 features.

I've found that this has the extra bonus of having more developers want to review your code because they know that they're going to be learning something new about ES6 during the review process.

Your team are already contributing to and editing a code-base that they're familiar with so the ES6 usage that they're learning is not contrived. It's real world.

5. Remove the ES6 comments


The comments labeled ES6: are there for training purposes. After a period of time you may want to remove them. This is easy to do in a search and delete of this type of comment in the code base.

If you have a lot of non-ES6 developers continually joining the project then you might not want to do this. You can also tag the repository before removing the comments so others can checkout that tag and read the comments.

You might also elect to start dropping comments for the easy-to-understand and common ES6 features and keep them in for the more complex scenarios.