4 ms·
All these routing libraries are just wrong level of abstraction. In HTTP you have resources, and resources are not flat, they are hierarchical. And hierarchy o
by peclink 10y ago
All these routing libraries are just wrong level of abstraction. In HTTP you have resources, and resources are not flat, they are hierarchical.
And hierarchy of resources defines some connection between then, and some common properties (data, access level etc). So any resource can respond to some HTTP method or can delegate to another, nested resource (if any) for any method.
So (in PHP, from our still proprietary framework):
// Index resource, just routing, no HTTP method handling.
class IndexResource extends Resource {
public function __construct(Application $app) {
// ...
}
// Route nested resources for any request
public function any(Request $request) {
// Static path:
$this->path(
CollectionResource::Path, new CollectionResource($this)
);
}
}
class CollectionResource extends Resource {
const Path = 'items';
// Parent resource type constraint, you can access
// parent data using IndexResource API:
public function __construct(IndexResource $parent) {
//...
}
// Route nested resources for any HTTP method:
public function any(Request $request) {
// Regexp pattern for URI segment:
$this->match(ItemResource::Pattern, new ItemResource($this));
}
// Or handle GET
public function GET(Request $request) {
// ...
}
// Or POST maybe
public function POST(Request $request) {
// ...
}
}
class ItemResource extends Resource {
const Pattern = '(\d+)';
public function __construct(CollectionResource $parent) {
// ...
}
public function any(Request $request, $prefix, $id) {
$this->item = Item::find($id);
}
public function GET(Request $request) {
return JSON::string($this->item);
}
}
It's not about routers + controllers etc, it's just resources + delegation to nested resources:
- recursive routes are trivial, so no problems with CMS-like applications;
- looks good with type systems;
- no long routing tables (in fact, no routing tables at all), so true modular apps;
- you can use anything (e.g. database) for resources lookup, good for CMSes again;
- it's absolutely RESTful.
Yes, automatic URI building is not so easy, but it's kinda possible, in some semi-automatic way.
I wonder why frameworks built this way are so uncommon (ours were inspired by Bullet BTW).
- twic 10y ago> In HTTP you have resources, and resources are not flat, they are hierarchical. That isn't really true. There is nothing about HTTP, or even REST, that requires resources to be hierarchical. That said, it is quite common, and helpful for human beings, if they are hierarchical, so ... > I wonder why frameworks built this way are so uncommon Good question! The only one that springs to mind is Stapler: http://stapler.kohsuke.org/what-is.html http://stapler.kohsuke.org/what-is.html
- peclink 10y agoThere is Bullet http://bulletphp.com http://bulletphp.com, that inspired us, but it is too simple and lacks some important (for us) features, e.g. recursion. There are nested routes in Express and some Golang libraries (see gongular near on HN), but they are not resource oriented. And yes, there are resources in Rails, but it's sooo complex and heavy.
- sthatipamala 10y agoOne downside I see to this: It's not possible to statically determine which resource will respond to which URL. I suppose that is also a benefit (maybe some resource can divert to another resource under heavy load/when its DB is unavailable). But quite frequently I want to answer this question with just the source code.
- peclink 10y ago> But quite frequently I want to answer this question with just the source code. Exactly. And that is also a benefit if routes are fetched dynamically from database, e.g. for content application, so your database is really content repository without too many levels of abstraction. As for source code, it's kinda silly to split your app to fixed «controllers» and «models», you should split it functionally for simple reuse. Most modern PHP frameworks are so unflexible that way (laravel is just terrible IMO).