RFC: Refactoring nette/application dependencies
- Jan Tvrdík
- Nette guru | 2595
Refactoring nette/application dependencies
This RFC proposes to split nette/application into 4 packages and reduce their dependencies.
Current state
Currently the nette/application contains the following responsibilities:
- Routing (
IRouter
,Request
,Routers\
) - Application life-cycle (
Application
,Responses\
,IPresenter
,IResponse
…) - UI layer (
UI\Presenter
,UI\Control
.UI\Form
…) - Micro framework (
MicroPresenter
)
Among the dependencies is nette/di
.
Proposed state
Note that the dependency on nette/di
will be entirely
removed.
Classes in nette/routing
package will be moved to new namespace
Nette\Routing
:
Nette\Routing\IRouter
Nette\Routing\AppRequest
(?)Nette\Routing\Routers\CliRouter
Nette\Routing\Routers\Route
Nette\Routing\Routers\RouteList
Nette\Routing\Routers\SimpleRouter
Proposed version
This RFC targets Nette 2.3 2.4.
Impact on backward compatibility
This breaks all packages which depend on nette\application ~2.2
and require anything from UI layer. We can possibly workaround this by creating
one more package but I recommend not doing so.
Rationale
- You can use routing independently.
- You can use micro-framework without installing tons of stuff you do not need
- Cleaner dependencies
Open questions
- Names of the 3 new packages.
- New name for
Nette\Application\Request
Nette\Routing\Request
Nette\Routing\AppRequest
Nette\Routing\ApplicationRequest
Nette\Routing\InternalRequest
Changelog
- Updated “Proposed state” section to mention impact on namespaces.
- Added new open question regarding new name for
Nette\Application\Request
Last edited by Jan Tvrdík (2014-11-02 14:52)
- Filip Procházka
- Moderator | 4668
@enumag you could do that by implementing custom IRoute
that will wrap the other routing lib.
- Jan Tvrdík
- Nette guru | 2595
No. The IRouter interface is very general, use adapter pattern if necessary.
- Jan Tvrdík
- Nette guru | 2595
@Milo Good question! A general rule of DI is that nothing should depend on DI container.
Presenter
has already been refactored by @DavidGrudl to
have DI\Container
as optional dependency only. We may remove the
dependency entirely or keep it as optional.
PresenterFactory
is a bit tricky. It currently has two
responsibilities:
- Mapping between
Application\Request::getPresenterName()
and class name. - Creating presenter instances
The first responsibility is OK, only the second one causes trouble. What
PresenterFactory
should receive instead of
DI\Container
is a list of factories / callbacks
(one for each presenter). Building of the list will be responsibility of someone
else. In our case it will be most likely a compiler extension. And yes, that
would require all presenters to be registered as services. We may probably
figure out some way to keep the registration optional. Although I'm not sure
whether we really want to make it optional (registering it has multiple
advantages).
Last edited by Jan Tvrdík (2014-11-02 12:47)
- Jan Tvrdík
- Nette guru | 2595
I've updated the RFC to mention impact on namespaces.
Last edited by Jan Tvrdík (2014-11-04 22:56)
- Honza Marek
- Member | 1664
@JanTvrdík Creating presenter instances is the main responsibility of PresenterFactory. Mapping between names and classes is just an internal detail (and part of the creation process).
- Jan Tvrdík
- Nette guru | 2595
@HonzaMarek Yes. The problem is that PresenterFactory
does not creates the instances itself but delegates the responsibility to DI
container. Which is wrong.
Last edited by Jan Tvrdík (2014-11-03 13:15)
- mkoubik
- Member | 728
Should Application\Request
really be part of routing? I think
the general router should map between Http/Request
and some bag
(array?) of parameters. Then there would be some bridge between routing and
application that would map these parameters (among them method, presenterName,
etc.) to Application\Request
.
- Filip Procházka
- Moderator | 4668
@JanTvrdík actually, I think we should go even further and not even
create instances using DIC (by the createInstance
method), but have
all presenter registered in DIC and then have them created using the DIC
properly.
- Jan Tvrdík
- Nette guru | 2595
2015 Summer Status Update
PresenterFactory
no longer (since Nette 2.3) depends on DIC. Good job!- All presenters are now (since Nette 2.3) registered in DIC. Good job!
- It is currently being discussed whether presenters (in general) can and should be autowired.
- RFC now targets Nette 2.4
This is still something I want to do. I once again work on a web application without HTML interface. Therefore I need to have installed the following packages even though they are useless for me.
nette/security
nette/reflection
nette/component-model
nette/application-ui
(as part ofnette/application
)nette/micro-fw
(as part ofnette/application
)
@DavidGrudl Would you accept this for Nette 2.4 or do we need to wait for 3.0?
- David Grudl
- Nette Core | 8218
Routing should be moved to new package nette/routing
, but it
must be independent on Nette\Application\Request
, ie.
nette/application
should depend on nette/routing
but
not vice versa. Routing can IMHO operate with simple array.
UI can be moved to new package, but it is not so easy, because there are some
dependencies in LinkGenerator
or Application
etc.
To create package micro-fw
that will contain only
MicroPresenter.php
is useless.
Dependency on nette/reflection
exists only for back
compatibility, due to
$presenter->getReflection()->getMethod(...)->hasAnnotation(...)
.
I'd like to remove it in future, but it is BC break.
Dependency on nette/security
will be needed (maybe) due to https://github.com/…ation/pull/4.
The fact that you need to have installed packages that you don't need is (unfortunately) normal. NPM installs tons of packages. After splitting into more packages you will have installed less number of packages (for you very rare usecase, application without UI), but majority will have to install more packages for standard use.
ad 2.4 vs 3.0: currently I have no release plan.
- Jan Tvrdík
- Nette guru | 2595
Routing can IMHO operate with simple array
Why not move Nette\Application\Request
to
nette/routing
as suggested in the original proposal? Because
it's too closely related to Nette\Application
? It seems a bit
strange to replace this
return new AppRequest(
$presenter,
$httpRequest->getMethod(),
$params,
$httpRequest->getPost(),
$httpRequest->getFiles(),
array(AppRequest::SECURED => $httpRequest->isSecured())
);
with this
return [
'presenter' => $presenter,
'method' => $httpRequest->getMethod(),
'params' => $params,
'post' => $httpRequest->getPost(),
'files' => $httpRequest->getFiles(),
'flags' => array(AppRequest::SECURED => $httpRequest->isSecured())
];
UI can be moved to new package, but it is not so easy, because there are some dependencies in LinkGenerator or Application etc.
That's why I wanted
LinkGenerator
to look more like Nextras LinkFactory.
Dependency on nette/reflection (…) I'd like to remove it in future, but it is BC break.
As long as users can override getReflection()
in
BasePresenter
it is easy to fix.
To create package micro-fw that will contain only MicroPresenter.php is useless.
I disagree with it being useless, although it is currently not as important.
NPM installs tons of packages.
NPM is bad example. It's problem are not small packages (which result in having a lot of them), but having tons of packages which do pretty much the same. So every time you install some NPM package, you end-up with multiple promise implementations, multiple process abstraction, tons and tons of utils packages and even more packages that I don't even understand why they exist in the first place.
you will have installed less number of packages (for you very rare usecase, but majority will have to install more packages for standard use.
Yes, that is good point. Although I would say that not using Application\UI is not that rare and we should educate people (this RFC is one of many steps) to not use Application\UI (e.g. for API or CLI) more.
ad 2.4 vs 3.0: currently I have no release plan
I don't care as much about the version number as about the probability that it would be merged if I started working on this.
- David Grudl
- Nette Core | 8218
ad router: only $params
are needed. The $presenter
can be extracted from $params
by nette/application
.
Everything else is direct copy from Nette\Http\Request
. So routing
can be really only about Http\Request → params and params → URL.
New nette/router
should somehow solve current shortcomings, like
$refUrl parameter, using modules, enabling https, etc.
ad application: nette/application
is closely tied to HTTP, so it
is not suitable to be used in CLI. It could be renamed to
nette/web-application
and new nette/cli-application
could be created, but more realistic is to have nette/application
and symfony/console
.
ad merge: of course I would merge it.
- Felix
- Nette Core | 1196
David Grudl wrote:
ad application:nette/application
is closely tied to HTTP, so it is not suitable to be used in CLI. It could be renamed tonette/web-application
and newnette/cli-application
could be created, but more realistic is to havenette/application
andsymfony/console
.
I'd love to have web-application
and
cli-application
. It could be next generation of framework based on
simple commands. Just nette way.