I have worked with most of existing PHP frameworks, but this is the first time I am working with Nette and unfortunately I can't make something which sounded like an easy task to work. How SHOULD it work:
How it WORKS:
After debugging and googling I found out that the problem is that I am trying to use the entity before I instantiated the model. The model object I am sending to the api handler class through DI (at least that's what I thought I'm doing), but when I try to var_dump it, I get the error message Typed property ... must not be accessed before initialization
This is how my configuration looks like for the API endpoints
services:
- App\Core\RouterFactory::createRouter
apiOutputConfigurator: Tomaj\NetteApi\Output\Configurator\DebuggerConfigurator
apiErrorHandler: Tomaj\NetteApi\Error\DefaultErrorHandler
# define apiKey in local.neon
staticTokenRepository: Tomaj\NetteApi\Misc\StaticTokenRepository([%apiKey%: '*'])
- Tomaj\NetteApi\Link\ApiLink
- Tomaj\NetteApi\Misc\IpDetector
apiDecider:
factory: Tomaj\NetteApi\ApiDecider
setup:
- addApi(Tomaj\NetteApi\EndpointIdentifier('GET', 1, 'get-endpoint'), \App\api\Handlers\GetEndpointHandler(), Tomaj\NetteApi\Authorization\NoAuthorization())
- addApi(Tomaj\NetteApi\EndpointIdentifier('POST', 1, 'post-endpoint'), \App\api\Handlers\PostEndpointHandler(), \Tomaj\NetteApi\Authorization\QueryApiKeyAuthentication('api_key', @staticTokenRepository))
This is how my configuration looks like for the ORM:
extensions:
nextras.dbal: Nextras\Dbal\Bridges\NetteDI\DbalExtension
nextras.orm: Nextras\Orm\Bridges\NetteDI\OrmExtension
nextras.orm:
model: App\Model\Orm
services:
- \App\Model\Repository\MyRepository(\App\Model\Mapper\MyMapper())
The names of the classes are of course censored for privacy reasons but they are not that important.
This is my entity
/**
* @property int $id {primary}
* LIST OF ALL OTHER PROPERTIES
*/
class MyEntity extends Entity
{
}
This is my mapper
/**
* @extends DbalMapper<MyEntity>
*/
class MyMapper extends DbalMapper
{
}
And this is the repository class
/**
* @extends Repository<MyEntity>
*/
class MyRepository extends Repository
{
/**
* @inheritDoc
*/
public static function getEntityClassNames(): array
{
return [MyEntity::class];
}
}
And last but not least the model class
/**
* Model
*
* @property-read MyRepository $things
*/
class Orm extends Model
{
}
I tried to inject the model object to the handler class simply like this (as I've seen in the demo)
#[Inject]
private Orm $orm;
but as the error messages say it's not working. What did I forget? As I wrote above this is the first time I am doing something with Nette so I'm pretty sure it's something what an experienced Nette dev would find immediately. I have also studied the demo which can be found here : https://github.com/nextras/orm-demo-nette but it woudn't help, I think I have everything done the same way - the only change being is they are injecting it to a presenter and I need to get it working in a Api handler. Thanks for any help.
EDIT: If I try to manually send the ORM in the constructor of the handler class, I am putting it to the config here (hopefully correctly)
apiDecider:
factory: Tomaj\NetteApi\ApiDecider
setup:
- addApi(Tomaj\NetteApi\EndpointIdentifier('GET', 1, 'get-endpoint'), \App\api\Handlers\GetEndpointHandler(App\Model\Orm()), Tomaj\NetteApi\Authorization\NoAuthorization())
- addApi(Tomaj\NetteApi\EndpointIdentifier('POST', 1, 'post-endpoint'), \App\api\Handlers\PostEndpointHandler(App\Model\Orm()), \Tomaj\NetteApi\Authorization\QueryApiKeyAuthentication('api_key', @staticTokenRepository))
I am getting a new error Service 'apiDecider' (type of Tomaj\NetteApi\ApiDecider): Parameter $configuration in Nextras\Orm\Model\Model::__construct() has no class type or default value, so its value must be specified.
So ... this is embarrassing but I found the error and it was on my side. For whatever reason creating an empty web application with composer generates Bootstrap.php which reads services.neon, but cloning our repo generates a Bootstrap.php where all config files have singular names, meaning service.neon . For some reason. In other words I was writing my configuration in a file which Bootstrap did NOT load. After renaming it properly, everything suddenly works as expected, what a surprise. Thanks for everybody's time, I'm going to silently rethink my life :)