Saturday, December 28, 2013

How can Rails react to the rise of the JavaScript applications?

The rise of JavaScript applications is tremendous. Every week new JS frameworks appear. Every website UI is now JS-heavy.

How can Rails react to it?

Do we need to worry about our jobs?

History

Let's go back to the history for a while.

Rails was created as a light-weight, but well-structured alternative to create dynamic, db-backed, html websites.

I still own the main Rails book, that was published in 2005: Agile Web Development with Rails. I just checked, there was 558 pages of good content. Only 16 pages were about The Web, V2.0 (this part was written by Thomas Fuchs, not by the main authors - DHH and Dave Thomas). Back then, Rails supported JS via the prototype library. There was no mention about RJS, yet.

Late 2006, I bought another book - Ajax on Rails. I have it in front of me right now. This time, RJS was important already, as they wrote: "Ruby-generated JavaScript (RJS) is the capstone of Ajax in Rails". Before the concept was introduced in the book, all the server did was returning HTML snippets (data) and the JS libraries inserted it into appropriate places. No such thing as view model, data-binding, etc, yet.


Where are we now?

Rails does a really good job of handling the backend part. It's secure, based on conventions, all apps are similar, everybody knows how to work with it.

Look at the frontend part of many Rails apps, though - you don't see the conventions, you don't see the same structure everywhere.

There's this pro-Rails argument, that it's better for a startup to do Rails, because many Rails devs will know what is going on if the project is done the-Rails-way - so, it's easier to scale the team. It's no longer true, though. Yes, the backend part is usually familiar, but the JavaScripts? They're completely different in every Rails app. Often, they're like 50% of the codebase.

Some developers just hack together some jQuery plugins and call it a day.

Some developers go with DHH suggestions and use RJS (UPDATE: or clean JS returned from the server) (to be honest I have never seen this approach in a Rails app, but I'm sure someone followed DHH here).

The new trend is to use JS frameworks, like Ember.js or Angular.js, which are opinionated and feel more aligned to the philosophy of Rails (conventions, magic, implicit features).

Other developers (me included) want to control the JavaScript app and don't use any framework, relying on self-imposed architectures like http://hexagonaljs.com/.

How can Rails react?

There are some possible ways of reacting. I'm trying to be neutral here, although obviously I have an opinion on that.

1. We can leave it as it is, with [R]JS being recommended by the leader

From my observations, the [R]JS recommendation gets ignored mostly. To be fair, none of the leaders is actively discouraging anyone to use some proper JS frameworks. It's just not the main focus.

This leaves the community disconnected from the leader (which may not be a bad thing). I've met many people who are worried for the future of Rails. They're not sure if Rails is a good technology to invest their time. For such people it may mean that in the longer run, they'll prefer to focus their education on the JS part more than on the Rails. We already see the increasing number of jobs ads requiring Angular or Ember.

This way, we'll see the trend started with rails-api growing in popularity.

2. Rails can adopt/recommend one of the JS frameworks.

It can be Angular or Ember. The first one has a huge growing trend recently. Ember is led by well-respected people from the Rails community (Yehuda). It's smaller overall but quite popular in the Rails world already.

We've seen a similar situation in the history of Rails, when Yehuda created Merb and then made it to Rails (oversimplifying a bit). Can the same happen with Ember? It's very likely.

What about Angular which is becoming the default JS framework? Can Rails recommend it? There's nothing in Rails that makes it hard to develop with Angular. But Angular is not the default choice, yet. DHH made some bold moves in the past, like making CoffeeScript on by default (thank you!). Can the same happen to Angular?

3. Rails will encourage JS frameworks but stays JS-framework-agnostic.

This is more or less what is happening already in the community. People use Rails together with many of the existing JS frameworks, with success.

4. All of the above

We can see DHH keep recommending [R]JS. The Rails core will make Ember the default choice, but easy to disable it. The community will keep using Rails together with everything.

The future

What is going to happen? I honestly don't know. Rails is doing fine-enough. It doesn't need to react in any way. We need to remember that it's not only about purely rational, technological choice. Rails was always famous for its marketing. We can see some unexpected moves, like coming up with its own JS framework.

What would I prefer?

Personally, the current situation is fine for me. I ignore the [R]JS way of creating the Rails apps. I'm allowed to create the JavaScript apps the way I want. Rails is good for API. I'm fine with any choice.

However, as I said, it's not only about rational choices, it's about the emotions. Do we want it or not, the Rails community is huge nowadays with new people coming every day.

If my main goal was to keep Rails hot for the new people, then I'd suggest choosing Angular as the framework that is on by default in Rails. That would bring a lot of love to the community. Angular is loved they way Rails used to be loved.  I personally don't really like the Angular way, but this choice will be good/easy for the new people for whom it's better to follow choices made by others.

In the meantime, other backend communities keep improving. Did you see PHP and Symphony2? It's a framework which is architecturally ahead of Rails (a topic for another blog post, probably). Did you notice how popular Scala is becoming?

Should we care about the future of Rails? Is it more pragmatic to be backend-independent and start learning more about other backend choices? Should we go the microservices way and have the app implemented in several backend technologies at the same time?

Many questions, lots of guessing :)

If you liked this blog post, you will enjoy following me on Twitter.

UPDATE: I changed RJS to [R]JS in some places. It's not really RJS that is recommended by DHH, but SJR - Server JavaScript Responses - see http://37signals.com/svn/posts/3697-server-generated-javascript-responses

Sunday, December 22, 2013

Decentralise id generation

It seems to be a common practice nowadays to rely on the database-generated, incremental id.

In one of our projects, we let the client-side (JS) generate the id (using guid/uuid). It leads to interesting consequences. We no longer need to send the form data to the backend immediately. If we want, we can create the object on the client-side, give it a guid, keep editing it and then send it back to the server, with the guid. The server stores the guid and uses it for identification. The same can happen at the same time from another Ruby client that connects to the same API.

This is how an example guid looks like:

f81d4fae-7dec-11d0-a765-00a0c91e6bf6


"A UUID is 128 bits long, and can guarantee uniqueness across space and time."

RFC: http://www.rfc-archive.org/getrfc.php?rfc=4122

"A UUID is an identifier that is unique across both space and time, with respect to the space of all UUIDs. Since a UUID is a fixed size and contains a time field, it is possible for values to rollover (around A.D. 3400, depending on the specific algorithm used)."

"Unless you're accepting IDs on, say, an Internet-wide scale, or with an untrusted environment where malicious individuals might be able to do something bad in the case of an ID collision, it's just not something you should worry about."

My opinion on UUIDs

For years, I have been thinking that centralised id generation is the natural way. Seems obvious. After I learnt mote about UUID, I start seeing more and more good things about it. It allows for less coupling between components/services.  You no longer need to 'ask' for the id. In case of JavaScript frontends it solves the problem of whether to block the UI, when we create a new resource.

The area, that I haven't researched much is having distributed database which you sync between the services. From what I know, it's already possible with http://www.datomic.com/.

Ruby 

Ruby has a built-in method:

http://www.ruby-doc.org/stdlib-1.9.3/libdoc/securerandom/rdoc/SecureRandom.html#method-c-uuid

p SecureRandom.uuid
# "2d931510-d99f-494a-8c67-87feb05e1594”

JavaScript

JS library
https://github.com/pnegri/uuid-js

var uuid4 = UUID.create();
console.log(uuid4.toString());
// Prints: 896b677f-fb14-11e0-b14d-d11ca798dbac


Python

>>> import uuid
>>> # make a UUID based on the host ID and current time
>>> uuid.uuid1()

UUID('a8098c1a-f86e-11da-bd1a-00112444be1e’)


Java

UUID uuid = UUID.randomUUID();



Also worth reading: http://stackoverflow.com/questions/703035/when-are-you-truly-forced-to-use-uuid-as-part-of-the-design/786541#786541

Saturday, December 21, 2013

The Four Architectures that will inspire your programming

This is the Big 4. The architectures, that may help your work. They may influence the way you think about programming.

1. The Hexagonal Architecture

(also known as the Ports and Adapters)

Originally described by Alistair Cockburn in http://alistair.cockburn.us/Hexagonal+architecture.
Enhanced and popularised by Steve Freeman and Nat Pryce, thanks to their book: http://www.growing-object-oriented-software.com/

2. Clean Architecture

Originally described by Ivar Jacobson, but popularised by Uncle Bob: http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html

3. DDD/CQRS

DDD: Domain-Driven Design
CQRS: Command Query Responsibility Segregation

Two separate concepts, but together create quite a unique architecture.
DDD is originally invented by Eric Evans. CQRS is often popularised by the work of Greg Young.

4. DCI

DCI: Data Context Interaction

James Coplien, Trygve Reenskaug
Desribed in James' book: http://www.leansoftwarearchitecture.com/ and here: http://www.artima.com/articles/dci_vision.html


What I think about them

I don't treat them as competitors. Learning the concepts behind them (still in progress) inspired me to bring some new ideas to our projects. Usually, they're not all or nothing.

The most mind-blowing architecture is definitely DCI. This is the future of programming. The vision of objects being different things in different contexts, while still keeping its identity is fantastic. Unfortunately, DCI is also the hardest one to use in day-to-day practice. Some of the concepts required (objects with roles) are hard to achieve in most popular languages.

The most practical architecture is possibly DDD/CQRS. There is a lot of example projects in many different languages. I love the pragmatic approach of splitting the system into Commands and Queries. At first, I couldn't get the point, but after more reading I see the beauty of it. I sometimes laugh that DDD could stand for (data) Duplication-Driven Design. It opened my eyes to the idea, that we can have multiple subsystems, each with its own storage. Some data will be duplicated this way, but it's often not a problem. The data is eventually consistent.

Another nice thing about DDD is the idea of Bounded Contexts. It's a terrible name, but a really useful concept of a module that encapsulates one little world of your project. Usually, you have one root object in each Bounded Context, which is called Aggregate. The same 'object' can exist in different BC, but will have a different name. Its identity will be kept via a unique id.

CQRS brings the concept of Commands being the most complex parts of your app, while Queries are usually very simple and don't require many layers.

What I like about the Clean Architecture is its focus on clear dependencies and on boundaries. Boundaries should be kept outside of your application. The communication between boundaries should happen via Data Transfer Objects. In the middle there's the Interactor, which represent a UseCase.

Last, but not least, we've got the Hexagonal Architecture. This is what inspired us mostly to create the JavaScript non-framework called http://hexagonaljs.com/. It's so easy to extract GuiAdapter and StorageAdapter, leaving the middle hex boundary-unaware.

HexagonalJS is a result of inspiration from all of the above architectures. We took the UseCase/Context part from the DCI architecture with a little bit of the Clean Architecture. The idea of adapters is taken from the Hexagonal Architecture. The middle hex is often implemented using the building blocks taken from DDD. Our unique addition to this setup is a little bit of Aspect Oriented Programming.

Often, when I'm in doubt how to approach a new project, I'm trying to stand far from the Upfront Design. However, it doesn't hurt if I imagine the project in each of the architectures. This gives me new ideas about the domain I'm implementing.


If you liked this blog post, you will enjoy following me on Twitter.


Friday, December 20, 2013

Turn a Rails controller into a Single Page Application


Single Page Apps are becoming more popular. When you see them in practice (GMail, Twitter, Facebook), it's quite cool. Then you look at your current project and you see how impossible it is to make it a Single Page App. Who's going to pay for that? It sounds like months of work, just replacing the whole existing functionality.

The thing is, it doesn't need to be the whole project at once. It's not all or nothing. You can make multiple small SPAs.

Where to start?

Look at your current Rails views/controller. Is there a clear widget, like a search bar, that could be extracted? That's a good candidate.

There's also another approach. Usually when you have a typical CRUD controller, it's always the same group of views. There's a list of things, that you can see, edit, update, add new items, etc.

Such controller is a good candidate for a SPA.

You end up with one view (index), which loads the JS. After the JavaScripts are initialised, an AJAX GET request is made to /index.json. This retrieves all the data for the list. Apart from that you need an API endpoint for creating, updating and deleting. Note that you don't need an endpoint for new/edit. They become JavaScript views, but they don't need to exist on the server-side. 

You turn the existing Rails views into handlebars templates (or whatever that renders the HTML client-side). They get rendered at appropriate moments by the JavaScript code.

If you prefer, you can use a framework for that. You can also do it on your own, as it's very easy. We usually go the hexagonaljs way - manual, with a nice structure and typical adapters: serverSide and guiAdapter. 

What does it give you?
  • Single Page Apps are architecturally better solutions than Rails views
    • it's easier to test
    • once you learn it, it's quite easy to write
    • there's strong decoupling between your frontend and the backend
    • the backend is simpler
    • the resulting SPA has less 'features' than a Rails view
      • by default, no URL for each 'view', just for the main one
        • good enough for most cases
      • for SEO you need to do additional work on the backend
        • not always needed
It doesn't need to be all or nothing

You can test the water by choosing some parts of your project and turn them into JavaScript apps. We're in the process of doing that in a large Rails project - I think, we're now with about 15 small Single Page Apps. We keep adding new features, it doesn't slow us down. Thanks to the faster build (it's easier to test decoupled components rather than a monolith), we're actually saving time.