garybernhardt / raptor

An experimental web framework.
368 stars 30 forks source link

How should applications be structured? #23

Closed garybernhardt closed 12 years ago

garybernhardt commented 12 years ago

Current application structure:

A Raptor application is composed of resources, which can contain routes, requirements, presenters, and records. The file layout matches the module hierarchy. E.g., the example application contains a "posts" file with classes like Posts::PresentsOne and Posts::Record. In a larger resource, these might be separate files like posts/presenters.rb and posts/record.rb, but that's the programmer's problem; Raptor doesn't know about files.

My concerns:

1) The number of things that can go in a resource. To the four above we'll add custom injection sources, and we've waffled back and forth on separating the record class into two: a record and a repository to hold queries. That would make six things that can go in a resource, and I'm sure we'll discover more.

2) The word "resource". A Raptor resource is not a resource in the REST sense, which bothers me. It's not self-contained and not necessarily exposed to the outside. I don't know what to name it without dropping back to something even more generic like "component", which makes me think that it's the wrong abstraction. Tom and I have struggled with this since we were first sitting in a coffee shop in Seattle thinking about Raptor with pen and paper.

Possible solution:

If resources are to be removed as a concept, the only option I see is a Rails-style separation: organize by type (presenter, etc.), then by name. Rails does this by file: app/models/post.rb, and its users often dump all of the resulting classes into the global namespace. If we did it, I'd want to do it by module scope, not file. You define YourAppName::Presenters::Post, regardless of how the source is laid out. Raptor will still guess at the names for defaults (as Rails does).

Problems:

Two things worry me about this change. First, it might turn apps into incomprehensible ravioli if the culture becomes "one class per file". Of course, this being Ruby, you could structure your files in the old way (posts.rb containing all post-related pieces). You'd just be reopening modules a lot. I'd really like to see how this works out.

Second, routes don't fit into this scheme as nicely as they do into resources. Currently, all routes are implicitly (and inescapably) prefixed with their resource name (e.g., "/posts/"). Decoupling the two means that you'll have to specify the prefixes somehow, and I fear descending into the hierarchical complexity of Rails routes (Raptor's routing is quite subtle as it is).

Do you share my fears about resource bigness? Do you share my fears about the module-based solution? Do you see another solution we've missed so far?

tcrayford commented 12 years ago

It's probably going to make startup time slower (and I'm already hurting from that). End to end specs take ~1s to start already (capybara webkit and sequel connection time, I guess).

Should raptor include asset serving itself?

garybernhardt commented 12 years ago

Moving the asset discussion to #34.

garybernhardt commented 12 years ago

I'm closing this. The module inversion has been in for a while. There are still outstanding questions, like raising vs. returning an error subject, but they're less pressing.