Pietro Menna Home page

Patterns and Integrations

I admit that I am upset that I have to consume an API from a front-end application that reads like methods from something like Java methods. Something like whatever-domain.com/getBusinessAreas.

I hear arguments like no one will consume the link directly, or access this address directly. I am still not convinced it is a good practice.

Patterns, patterns, patterns…

Why do we have Patterns in the Software Industry? to communicate with other developers.

Just like design patterns, there are other types of patterns. The king of Pattern that was violated by the API mentioned before is called an Integration Pattern.

There are a lot of Integration Patterns, just to name some: RMI, SOAP, REST, Message Channels, Pipes, and many others. The ones I am interested here are SOAP and REST.

Choosing between SOAP and REST

##SOAP##

SOAP exposes a service, by using a Service Descriptor (right, the WSDL file). All communication is via this service, and it uses an XML “Envelope”.

SOAP in the web came in disuse. I will not say it is dead, a lot of services still use it. Eg: Jira.

I still believe it might be useful in some scenarios. But I am quite sure it not designed for UI-centric consumptions such as browser consumption. So, if a front-end in HTML5 will consume, do not go for SOAP.

REST

It is an Architecture Style. Every RESTful service must respect certain constraints: Client-Server, Stateless, Cacheable, Layered System and Uniform Interface.

A simple example: putting the previous service to REST.

The example from the beginning of this post, could have easily have been named as: GET /BusinessAreas. It would retrieve the list of “Business Areas” that exist in the system.

We could have retrieved the details of one specific, like BusinessArea “1” simply by GET /BusinessAreas/1.

To create a new “Business Area”, we could use POST /BusinessAreas/. In the body of the POST we send the details required to create one.

To update the details for a given business area, we could use PUT /BusinessAreas/1

At last, in order to delete one Business Area, we could use DELETE /BusinessAreas/1. The example would have updated Business Area 1.

#Conclusion

The REST approach allowed to remove the ugly camelCase Java like. But actually, the architectural style significantly improves the readability of the service. Imagine you have more entities, they would all follow the same pattern for access.

Does it look simpler? To me at least, yes. It looks a lot better thanks to uniform access pattern gained by following a simple standard.

Jekyll adjustments for Blaggregator post-rc

It has been a long time since I got back from Recurse Center, and only now I realized that everything I write here still will appear on Blaggregator (An awesome service that I check out like every two days that contains blog posts from recursers).

How does Blaggregator works?

Once you subscribe to Blaggregator, it is possible for you to “Add your blogs” to it. By adding your blogs I mean you are able to add feed urls (RSS and Atoms I guess).

I there is a job which grabbs the feeds and parses it to see if there is a new entry.

Awesome, so what is the problem?

It turns out, I am using Jekyll, and when I suscribed to blaggregator I added the feed that came with the theme I use. All my posts are going to Blaggregator.

In order to be able to select what gets into Blaggregator, I will need to adjust the file which is generated by Jekyll as atom.xml or create a new one specially for the service.

Jekyll Adjustments

  1. I copied the current atom.xml to atom_rc.xml. This way, I will have one full feed for the site, and one only for blaggregator for the RC related posts.
  2. I marked the relevant posts, with category recurse-center. Each post which shall be included in this new file requires this “tag”.
  3. Added the code which only picks if category contains “recurse-center”. Lines 18 and 27 of this GitHub gist.
  4. Remember to update your link at Blaggregator!

Conclusions & maybe apologies!

Maybe this is useful for other recurses which may also would like to select the posts which gets listed in blaggregator. This is the intention!

Apologies if by making this change in my blog all my old posts gets re-published! :-(

Rails 4.2, Vagrant and ... Problems!

I started a new personal project. I set up Vagrant so I can have the “same” development environment across all computers.

The project uses Ruby on Rails, so I set up the line below in the Vagrantfile.

config.vm.network "forwarded_port", guest: 3000, host: 3000

It means forward port 3000 from the guest as if it was 3000 on the host.

I started up the virtual machine and ran rails server. From the host I fired up Safari open address http://localhost:3000. I expected to see my app, but what I saw was:

CannotOpen

Of course, browsing on the Internet for possible solutions was the next step. All the effort I spent Googling was in vain. In part because I looked for everything in the log which may seem like a problem, like:

default: The guest additions on this VM do not match the installed version of
default: VirtualBox! In most cases this is fine, but in rare cases it can
default: prevent things such as shared folders from working properly. If you see
default: shared folder errors, please make sure the guest additions within the
default: virtual machine match the version of VirtualBox you have installed on
default: your host and reload your VM.
default:
default: Guest Additions Version: 4.3.10
default: VirtualBox Version: 5.0

Totally misleading and the wrong approach for this particular problem.

##The analysis##

How does vagrant ssh work but rails server not? Both rely on port forwarding This was the starting point question.

I tried listening with nc (netcat) on port 3000 and making a requests from the host. Unfortunately no response again:

nc -l localhost 3000

No matter what I sent to port 3000 on the guest, it was not reached.

So nothing to do with Rails, right? No, but yes! I don’t know why, but I read the manpage for nc, and found out that -p is for ports, by trying nc -l -p 3000 I could reach the guest from the host on the desired port.

vagrant@vagrant-ubuntu-trusty-64:~$ nc -l -p 3000
GET / HTTP/1.1
Host: localhost:3000
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
If-None-Match: W/"b56dd5f9363ed0f7bd4d11c36d9471dd"
Cookie: _ga=GA1.1.1880364256.1438043513
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/600.7.12 (KHTML, like Gecko) Version/8.0.7 Safari/600.7.12
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: keep-alive

But what does Rails have to do with it?

Reading the change log from Rails 4.2 here. We can find the text below:

“Due to a change in Rack, rails server now listens on localhost instead of 0.0.0.0 by default “

##What I learned##

127.0.0.1 (or localhost) is not the same as 0.0.0.0.

The ip address 0.0.0.0 means all IP addresses on the local machine. It includes all interfaces, including the virtual interface used by virtualbox.

127.0.0.1 is the “loopback connection”, it is only be available from the same host/system. In this case, it was the guest virtual machine. This was the reason why I could not reach from the host. The guest is a different host/system than the guest.

##The solution##

Make rails listed on 0.0.0.0. This can be achieved by running rails server this way: bin/rails server -b 0.0.0.0, or by changing file config/boot.rb to include:

require 'rails/commands/server'

module Rails
  class Server
    new_defaults = Module.new do
      def default_options        
        default_host = Rails.env == 'development' ? '0.0.0.0' : '127.0.0.1'
        super.merge( Host: default_host )
      end
    end

    # Note: Module#prepend requires Ruby 2.0 or later
    prepend new_defaults
  end
end

If you make this change, you can just use rails server as usual.