loading...

re: Booster framework vs Ruby on Rails VIEW POST

FULL DISCUSSION
 

I took a look at the code in both repos and I gotta say that the code in the RoR repo looks way easier to read, understand, and work with than the code in the Booster repo (disclaimer I work with Rails and JS on the daily but have had only basic experiences with TypeScript). I do like the directory structure in Booster but the actual code in the files is just, well, TypeScript. Just take a look at the Message models:

# /app/models/message.rb

class Message < ApplicationRecord
  belongs_to :user
  belongs_to :chat_room
  validates :body, presence: true, length: {minimum: 2, maximum: 1000}
  after_create_commit { MessageBroadcastJob.perform_later(self) }

  def timestamp
    created_at.strftime('%H:%M:%S %d %B %Y')
  end
end
// src/read-models/MessageReadModel.ts

import { ReadModel } from '@boostercloud/framework-core'
import { UUID } from '@boostercloud/framework-types'
import { Projects } from '@boostercloud/framework-core'
import { User, Admin } from '../roles'
import { UserProfile } from '../entities/UserProfile'
import { Message, MessageType } from '../entities/Message'

@ReadModel({
  authorize: [User, Admin],
})
export class MessageReadModel {
  public constructor(
    public id: UUID,
    readonly chatRoomId: UUID,
    readonly body: string,
    readonly messageType: MessageType,
    readonly createdAt: string,
    readonly createdBy: UserProfile
  ) {}

  @Projects(Message, 'id')
  public static onMessageCreated(message: Message): MessageReadModel {
    return new MessageReadModel(
      message.id,
      message.chatRoomId,
      message.body,
      message.messageType,
      message.createdAt,
      message.createdBy
    )
  }
}

Honestly, I don't even think you need to know much about Ruby or Rails to be able to read the RoR version. Not to mention you have to jump to src/events/chatRoom/MessageCreated.ts to see that something happens after the message is created. I actually took me a few minutes to figure out where this was because there's an events and an events-handlers directory. I was then looking for an events/message directory but it was in the events/chatRoom dir.

Additionally, I don't think that having authentication and authorization built in is necessarily an advantage. There are great gems that integrate seamlessly with Rails to handle those and not having them baked in means I can choose the one that fits my needs or even roll my own. When it's baked in you take away a lot of choice and restrict people from using a better library, unless you feel like monkey patching (not that that's a bad thing).

As for cost, it kinda feels like you're deliberately jacking up the price of the RoR version. Maybe you're not, Heroku is fairly popular and well known, but there are better, more cost effective options. For example, Hatchbox offers similar (if not better) features at a fraction of the cost (Your $650/mo. Heroku estimate turns into ~$150/mo.). Heck if you really want to use AWS you could do a similar RoR deploy on AWS for ~$300.

This isn't me bashing Booster. After reading through your docs it sounds like you have a pretty cool framework. Definitely seems like a solid choice for building a communication app. However, I think building an example app that plays directly to your frameworks strengths and then comparing it to a framework that isn't purpose built for that kind of app is a little unfair, hence my reply.

 

Hi @drbragg , first of all, thanks for your constructive criticism and for taking the time to look into Booster; I think you hit the nail in many interesting topics where we can improve.

I used to write a lot of Rails code before switching to other things, and for me, and as it happens to you, the Rails version looks natural and 100% understandable, but after mentoring a couple of developers in their journey to Rails, I can tell you that it's easy for experts to forget the amount of knowledge packed in little things like a belongs_to or an after_create_commit.

As a major contributor of Booster, I would be extremely biased to say that the TypeScript version is "simpler", but what I can say is that the framework is still young and that the goal is to make it simpler over time. For instance, talking about the code sample you pasted, one thing we've thought is emulating Ruby's autoload to remove all these imports from the user's code. There are also plans to make projections implicit by default, as they're often just copying the data from entities. With that change, the Booster ReadModels become almost only data structures.

One thing that can surprise you at the beginning is that Booster uses a totally different architecture than Rails, as it's based on CQRS and Event-Sourcing instead of MVP, so you have to think differently about your code. In Rails, you can easily follow everything that happens when you hit a controller by just reading the code in the corresponding method. In Booster, a command only stores an event, and you can't tell what happens after the event is stored by just looking at the code. The way to do that is searching for the registered event type to see what event handlers and entities are observing it. I think that it could make a lot of sense to develop some IDE integrations that help to visualize this.

Regarding costs, the main difference between Booster and Rails is in the delivery mechanism and its price model more than the specific price or service you choose to use. I think that @j2rguez was just sharing typical configurations here, but you can always tweak your config to build much more cost-effective solutions. Booster currently works on top of AWS Lambda and DynamoDB, which have very different price models than VPS or database instances, but in the future we're planning to support deploying Booster applications on Kubernetes clusters too, where the price model is much closer to Rails'. Indeed, the opposite can also be done, you could deploy a Rails app in AWS lambda to get the same pricing benefits using Jets Afterburner, but that's probably only for the experts and the bravest :-D

 

Booster is definitely a very different architecture than Rails, which is why I felt compelled to respond when Rails was used as a comparison framework. It's like comparing how effective a screwdriver is verses a hammer for putting a screw in a piece of wood. Booster is built to easily build this example where Rails is not. I would love to see it stacked against other node based frameworks or against something else in the serverless world like Go.

Booster is an extremely cool project and I'll definitely being following its development.

Thanks for your kind words, we're always looking to keep improving Booster, and conversations like this are very useful for us! If you try it, feel free to send some issues with questions, suggestions, or feature requests!

@j2rguez is a great Rails engineer that we've been trying to "evangelize" into Booster for a while, and I can't hide that seeing him writing this article and defending Booster over his favorite framework makes me happy, but yes! Booster and Rails are very different projects that are hard to compare. Indeed a purely CRUD application is likely to look way simpler in Rails, but this is still a good exercise to understand how Booster compares to existing frameworks.

As a new framework that's trying to find its place, there's a recurrent question from devs that look at it for the first time: how does it compare to my current framework, and why should I consider switching or doing my next project in Booster?

Seeing the same application implemented in both frameworks is a good starting point to answer that question, but this example only explores one subset of everything that Rails can do, and probably not the best one. It would be interesting to see an article written with the opposite approach, starting with an app that fits well in Rails to see how Booster copes with it, I bet we'd find a lot of interesting ideas for future releases!

 

One last thing, you may want to consider using the tag #showdev and/or swapping out the #rails tag for the #typescript or #node tags since they are a little more relevant to what you're promoting and will get you better exposure to the right people (I only stumbled upon this post because I was scrolling through the #rails tag feed)

Code of Conduct Report abuse