Open MichalLytek opened 6 years ago
Why find-my-way
? It does not look popular and future is seamless and unpredictable for this lib, there are tons similar libraries most of which are not maintained anymore. What it does inside what makes it so quick? They all use embedded node server functionality, right? Then why can't we do same (even if exactly same) what those library do?
From beginning I wanted to create separate fast-as-possible driver for routing-controllers. Not based on express koa or anything else. Native, dependency-less, ultra-fast solution for routing-controllers.
Why find-my-way ? It does not look popular and future is seamless and unpredictable for this lib, there are tons similar libraries most of which are not maintained anymore.
I've just read the article about fastify framework and they are using the find-my-way
. Looks like it's very fast so it makes sense to make a big refactor as we may gain nice performance improvements.
What it does inside what makes it so quick?
It use different approach than regexing path, as described in readme - it internally uses an highly performant Radix Tree (aka compact Prefix Tree). Some weird paths like /hello/:my-:world.html
are not supported yet but 99% of the use cases of normal rest apis are covered.
Then why can't we do same (even if exactly same) what those library do?
I'm not an expert in tree-like algorithm, as well as in optimization 😜 If you have knowledge to create a fast router and maintain it you can do it, I'm not able to do this so I need to use 3rd party libs.
If you have knowledge to create a fast router and maintain it you can do it,
okay maybe some day. If you can't then we can simply add new driver. But I think its better to add it fastify, not find-my-way
. This will give us more advantage (and probably almost zero disadvantage) over find-my-way
If you can't then we can simply add new driver.
I don't think that it's necessary. Fastify is a express-like framework with no special features, just with renamed res
to reply
and others small features like built-in logger, lifecycle hooks. They even maintained compatibility with express middlewares. But as you said:
It does not look popular and future is seamless and unpredictable for this lib, there are tons similar libraries most of which are not maintained anymore.
The only pros of fastify is that it's fast thanks to fast router and json serialization library that use schema - later we could think about JSON schema stringify too. I just wanted to speed up existing apps with koa or express, not to introduce third driver which would complicate developing features.
I've even done some benchmarks of the frameworks:
So it looks like it makes sense to think about custom router or even "dropping both Koa and Express in favour of packages like find-my-way and connect since it will give you the most flexibility in developing routing-controllers and not being reliant on the API of express or koa, or both.". But for this we would have to cover all the remaining use cases that users are now forced to use bare req/res/ctx methods.
We are getting close to the final API and functionality
There will be things to improve always ;)
It does not look popular and future is seamless and unpredictable for this lib,
@pleerock the first commit was 5 months ago, so its young thats why it's not popular. With this magnitude of difference I think it will definitely get some traction.
Some weird paths like /hello/:my-:world.html are not supported yet but 99% of the use cases of normal rest apis are covered.
@19majkel94 this looks good, but we should not add it if it makes some regression. But we should keep an eye for this it looks promising.
If you can't then we can simply add new driver. But I think its better to add it fastify, not find-my-way. This will give us more advantage
I agree with that, it clears that for fastify/fastify performance is top 1 priority. If we can switch we should switch and enjoy the free performance gains with every release. Of course for this we need some preparation and check if we wont have any regression.
"dropping both Koa and Express in favour of packages like find-my-way and connect since it will give you the most flexibility in developing routing-controllers and not being reliant on the API of express or koa, or both."
don't even think about it. Express and koa under the hood of routing-controllers is not reasonless. With express and koa users who want to use routing-controllers will use it only because it supports thing they already know and like with all its features and middlewares. If routing-controllers go with its own (or any other non popular solution) from beginning it could not achieve even 10% of its current popularity. We can't dictate rules what to use for users yet.
If we integrate this new thing I think it should be a new driver. People who don't need express/koa middlewares and want to be extra-fast will use it. Others who needs express features/infrastructure/middlewares/community will use express driver.
People who don't need express/koa middlewares and want to be extra-fast will use it.
It has compatibility with express middlewares and the api is 90% the same, so it's not at much different framework that drops compatibility.
With express and koa users who want to use routing-controllers will use it only because it supports thing they already know and like with all its features and middlewares.
But what is the difference for routing-controllers users that use decorators abstraction? They even might don't remember what driver they are using until they need to do something that can't be done in routing-controller way, so they need to inject bare req/res and do it on their own. We can provide support for connect middlewares to get access to the big base of middlewares, so we wouldn't stand aloof alone.
They even might don't remember what driver they are using until they need to do something that can't be done in routing-controller way, so they need to inject bare req/res and do it on their own.
Don't judge by only yourself. People may use Req
and Res
decorators and some underlying express functionality. People in 90% percent use express middlewares.
I think this idea to use a new ultra-fast alternative to express is good, but I think it must be a separate driver. Those who don't need express functionality and want to use ultra-fast thing instead will just use this new driver.
People in 90% percent use express middlewares.
And fastify/potential future version of routing-controllers could use them too as they are compliant to connect middleware spec.
So if users can use 3rd party middlewares and we fill the gaps of express methods (so all can be done with decorators, no need for req/res), the underlying driver will be transparent so we could replace it with our custom router and better integrate the logic into the stack, right?
and we fill the gaps of express methods
but we can't cover every use case with decorators. Also we don't know how users use express in their apps. There can be lot of different usages. Maybe we can cover some of them but it seems risky to simply remove express from the lib.
Conversation in this issue and "drop koa support" overlap, so I'll repeat my concerns here again:
I understood what you want. Your goal is to bring routing-controllers into the next level. I like this goal, I would like to do it as well. However in my opinion next level is something greater then removing express in favour of fastify or some router. Next level is to have a complete standalone framework just like express or koa or fastify are. I see next level as a separate framework, not called routing-controllers, without any dependencies. It should be fast, efficient, with decorators, typescript friendly, and simply great. Im sure all together we can do it. However at the moment Im really very very busy with typeorm (thats what is real pain, not one-file koa driver) and I can't do it right now. I suggest you to add a new driver if you want to use it so much and in the future once I get rid of all planned typeorm features and issues and I'll return back to this issue and we'll do a new really great brand-new framework based on what you gonna do in this new driver.
I don't want to change concept of routing-controllers (just like its name) even in version 1.0.0. I want it to support all exist drivers and even new drivers. It should already be complete library and I don't afraid of many new issues including issues with koa, since framework is almost complete I don't think we gonna have of them.
I've done second test with routing-controllers using express:
So we had 20% overhead now for things that doesn't involve class-validator, transforming and middlewares.
I think we should expose generic createServer
function to even make drivers as extensions modules - fastify or restify doesn't have to be for now here in codebase. The usage would be simple:
import { FastifyDriver } from "fastify-routing-controllers";
import { createServer } from "routing-contollers";
const app = createServer(FastifyDriver, {
controllers,
midddlewares,
});
https.createServer(cert, app).listen(3000, () => console.log("routing-controllers fastify is live on 3000"));
We have overhead not because of extra drivers we have, but because of code that makes things to work we have. We need to optimize code as we can to reduce overhead. I don't think its a good idea to extract all drivers into separate packages because it will make things much more complicated.
Express and koa can be built-in drivers but we just a bit modify current code to make it work with 3rd-party drivers. To simplify the code they may use the same generic api covered under the hood by existing createExpressServer
function for compatibility :wink: I will create a PR today to show you how it may looks.
We have overhead not because of extra drivers we have, but because of code that makes things to work we have
We have some overhead because of drivers abstraction - we can't do some things directly and fast as we could when working directly with node.js req/res. Of course it's not the root of 20% but one of the main factors.
Stale issue message
@MichalLytek Any update on this?
For now we rely on the routing of the underlying driver (express or koa). However express and koa routers are really slow, as you can see in benchmarks: https://github.com/delvedor/router-benchmark
As we handle the route concatention and param injection by themselves, we could perform the routing at the (nomen omen) routing-controllers level using the
find-my-way
router library: https://github.com/delvedor/find-my-wayWe are getting close to the final API and functionality, so we should consider now also optimization and performance of the framework 😉