Hi @solnic, before to reply to all your doubts, I want to point out that you’re questioning if the project worths to exist and at the same time you’re pretending to build a new Ruby ecosystem with us.
You suggest to ditch hanami-validations and hanami-model in favor of dry-validation and ROM. Well, we can do that, but what’s the where Hanami can be useful for this new ecosystem? What we can build together? In the past months I’ve seen you to adopt roda, to build dry-view and than dry-web, which are overlapping hanami-router
, hanami-view
and hanami
gems. Are we still building something together? Or is that collaboration one way?
Here’s my answers:
Is hanami becoming another rails?
What do you mean exactly?
What is it exactly that hanami has to offer that will be a game changer? Is it supposed to be a slightly better version of rails?
I always thought to Hanami as a sane alternative to Rails in terms of light, speed, maintenance and testability. We want to offer the same amount of Rails features. I’m talking about all the facilities that developers find really convenient: think of code generators, migrations, assets.
At the same time, the interfaces aren’t bloated, and a Hanami project is way lighter and faster than one built with Rails.
The architecture is goes beyond flat MVC (“fat models, skinny controllers”), which proved to be painful for maintenance. What we offer is full MVC, where there are more collaborators to assign responsibilities: real view objects, presenters, interactors, etc…
Still on maintenance. I’ve been burnt by Rails major release upgrades: form 1.2 to 2.0, 2.3 to 3 etc… and we want to avoid developers to experience this problem with Hanami. We value the effort (time and money) of companies and individuals that are investing in Hanami projects. I’m so strict with dependencies and interfaces, because this is the way to keep Hanami stable over the time.
Less coupling. We avoided Rails mistakes of components coupling: each layer knows about ActiveRecord. With Hanami you can’t do <%= link_to @book, 'Title' %>
and expect it to work, because the routing is completely decoupled from the ORM. Even better, hanami-model
isn’t even a dependency, you can drop it from Gemfile
and use which data source you want.
Testability. Unit testing is simplified: you have less setup, you can inject dependencies and avoid ugly hacks like any_instance
. Everything is an object. If you need to test it, just send a message and verify the output. Hanami is the first web framework that allows to instantiate actions. How testing can be simpler than this? response = Action.new.call({id: 23})
Embrace Ruby (Ecosystem). We grew Hanami without diverging from Ruby: no monkey-patching, nor constant autoloading, the list is longer… We don’t mess with the language. Every time you’re in doubt, you don’t need to ask how would you do something with Hanami, but better to ask how would you do with Ruby.
Since the beginning we wanted Hanami to play well with external libraries. I already mentioned that you can use any data source (or ORM) you want. You can bring any Ruby library that you want (unless it targets Rails specifically). You can use any Rack middleware you want, authorization libraries like pundit, queues like sidekiq.
What is the philosophy of this project? Is it becoming a part of the new ruby ecosystem that I thought we’re building or is it a thing of its own, a closed microecosystem that wants to be in control and impose weird constraints for other libs to make them work with hanami?
I’ve probably already answered to this question with the last point above. In short: we don’t aim to become a closed walled garden.
If we communicated this impression, it’s a big misunderstanding. Our goal is to protect developers from the changes that low level engines may introduce. Think it as a gigantic Dependency Inversion Principle: we want our developers to depend on Hanami abstractions instead of concrete implementations. For rendering a template, developers can rely on stable abstractions of hanami-view
’s interface, even if its low level engine (tilt
) will change.
Why does it even need a validation library?
For the same reason, even if we adopt dry-validation
as backend, hanami-validations
still makes sense to exist.
The reason why I started a validation library is simple: I didn’t had chance at the time. The first release (v0.1.0) is dated Oct 2014, at that time DRY wasn’t there yet. The only alternative was to use activemodel, but that wasn’t possible because of different visions with that Rails world.
Will using any validation library going to be a problem?
It depends. If you expect params validations to have a swappable backend the answer is no. For any other usage the answer is yes. For instance, you can use dry-validation
like this:
module Web::Controllers::Books
class Create
include Hanami::Action
def call(params)
schema = Dry::Validation.Form do
# ...
end
result = schema.call(params.to_h)
# do something interesting
end
end
end
So it’s NOT gonna be a problem in general, because Hanami it’s just Ruby.
Why does it have a model/orm lib?
Same reasons of the validations: protect from changes and because at the time (Apr 2014), ROM wasn’t ready yet.
There is also another reason to keep hanami-model
: migrations and database tasks (create, drop, prepare).
Will using any orm going to be a problem?
Again no. Here’s the how to do:
hanami new bookshelf
cd bookshelf
rm -rf lib
vim Gemfile # remove `hanami-model` in favor of anything else
bundle
Why does it have hanami-utils, which is essentially ActiveSupport without monkeypatches, are there maybe any missing abstractions that you’re trying to workaround by having “util apis”?
This is a wrong question. Sorry, but that means you haven’t understood hanami-utils
at all.
Most of the times, It provides objects for internal Hanami usage: deprecation warnings, class attributes, callbacks. These utilities aren’t exposed to developers, we just needed a place (gem) to share common code across Hanami libraries.
You’re talking about “missing abstraction”, which is another way to ask if it suffers from Primitive Obsession. Short answer: no.
Long answer: There are a couple of cases (Utils::String
and Utils::Hash
) that may lead you to think about Primitive Obsession. But we don’t suggest developers to use them. We don’t even use them directly in the framework implementation.
Here’s a concrete example: application name. When you create a new application, Hanami translates the name you pass as input into a Ruby constant name string (eg. "cool_app"
into "CoolApp"
). To do that we use Hanami::ApplicationName
, which is an abstraction that internally uses Utils::String
.
hanami-utils
has other abstractions like LoadPaths
(instead of an array of pathnames, which are primitives), PathPrefix
(instead of a Utils::String#to_path_prefix
primitive).
Why do you think your opinionated stack will be so much better than rails?
Already answered at the beginning. Who share that values with us, will probably appreciate Hanami.
Will using hanami feel like it’s “on top of the tool chain”? Will it control the developer or will the developer control it? Will it play nice with others or not? Is that even a concern for the hanami team?
It’s a concern for us! For sure! We don’t want to be at the top of the chain. Have you ever tried to mount Hanami into Rails? I’m running it in production. Have you ever tried to do the opposite? You can’t.
I haven’t tried with other Rack based frameworks, but theoretically you can entirely remove the shell around a Hanami project and it still works as it’s just a Rack application.
I hope to have answered to all your questions. Feel free to ask more and don’t forget to reply to mine at the top. Thanks