Skip to content

Commit 3173c3a

Browse files
authored
Merge pull request #111 from Howriq/issue-93
Issue #93: Strictly following the book tutorial some routes does not …
2 parents 00e6a67 + d68dd21 commit 3173c3a

File tree

2 files changed

+78
-224
lines changed

2 files changed

+78
-224
lines changed

docs/book/v5/tutorials/create-book-module.md

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ $nameInput->getValidatorChain()
511511
$this->add($nameInput);
512512
```
513513

514-
Now it's time to create the handler.
514+
Now it's time to create the handlers for the book entity and book collection.
515515

516516
* `src/Book/src/Handler/BookHandler.php`
517517

@@ -532,19 +532,18 @@ use Mezzio\Hal\ResourceGenerator;
532532
use Psr\Http\Message\ResponseInterface;
533533
use Psr\Http\Message\ServerRequestInterface;
534534
use Psr\Http\Server\RequestHandlerInterface;
535-
use Dot\DependencyInjection\Attribute\Inject;
536535

537536
class BookHandler extends AbstractHandler implements RequestHandlerInterface
538537
{
539538
#[Inject(
540539
BookServiceInterface::class,
541-
"config"
540+
"config",
542541
HalResponseFactory::class,
543542
ResourceGenerator::class,
544543
)]
545544
public function __construct(
546545
protected BookServiceInterface $bookService,
547-
protected array $config
546+
protected array $config,
548547
protected ?HalResponseFactory $responseFactory = null,
549548
protected ?ResourceGenerator $resourceGenerator = null,
550549
) {
@@ -580,7 +579,52 @@ class BookHandler extends AbstractHandler implements RequestHandlerInterface
580579
return $this->createResponse($request, $book);
581580
}
582581
}
582+
```
583+
584+
* `src/Book/src/Handler/BookCollectionHandler.php`
585+
586+
```php
587+
<?php
588+
589+
declare(strict_types=1);
590+
591+
namespace Api\Book\Handler;
592+
593+
use Api\App\Exception\BadRequestException;
594+
use Api\App\Handler\AbstractHandler;
595+
use Api\Book\Service\BookServiceInterface;
596+
use Dot\DependencyInjection\Attribute\Inject;
597+
use Mezzio\Hal\HalResponseFactory;
598+
use Mezzio\Hal\ResourceGenerator;
599+
use Psr\Http\Message\ResponseInterface;
600+
use Psr\Http\Message\ServerRequestInterface;
601+
602+
class BookCollectionHandler extends AbstractHandler
603+
{
604+
#[Inject(
605+
BookServiceInterface::class,
606+
"config",
607+
HalResponseFactory::class,
608+
ResourceGenerator::class,
609+
)]
610+
public function __construct(
611+
protected BookServiceInterface $bookService,
612+
protected array $config,
613+
protected ?HalResponseFactory $responseFactory = null,
614+
protected ?ResourceGenerator $resourceGenerator = null,
615+
) {
616+
}
583617

618+
/**
619+
* @throws BadRequestException
620+
*/
621+
public function get(ServerRequestInterface $request): ResponseInterface
622+
{
623+
return $this->createResponse($request, $this->bookService->getBooks(
624+
$request->getQueryParams()
625+
));
626+
}
627+
}
584628
```
585629

586630
After we have the handler, we need to register some routes in the `RoutesDelegator`, the same we created when we registered the module.
@@ -590,8 +634,12 @@ After we have the handler, we need to register some routes in the `RoutesDelegat
590634
```php
591635
<?php
592636

637+
declare(strict_types=1);
638+
593639
namespace Api\Book;
594640

641+
use Api\Book\Collection\BookCollection;
642+
use Api\Book\Handler\BookCollectionHandler;
595643
use Api\Book\Handler\BookHandler;
596644
use Mezzio\Application;
597645
use Psr\Container\ContainerInterface;
@@ -607,13 +655,13 @@ class RoutesDelegator
607655

608656
$app->get(
609657
'/books',
610-
BookHandler::class,
658+
BookCollectionHandler::class,
611659
'books.list'
612660
);
613661

614662
$app->get(
615-
'/book/'.$uuid,
616-
BookHandler::class,
663+
'/book/' . $uuid,
664+
BookCollection::class,
617665
'book.show'
618666
);
619667

@@ -678,6 +726,7 @@ class ConfigProvider
678726
BookHandler::class => AttributedServiceFactory::class,
679727
BookService::class => AttributedServiceFactory::class,
680728
BookRepository::class => AttributedRepositoryFactory::class,
729+
BookCollectionHandler::class => AttributedServiceFactory::class,
681730
],
682731
'aliases' => [
683732
BookServiceInterface::class => BookService::class,

docs/book/v6/upgrading/UPGRADE-6.0.md

Lines changed: 22 additions & 217 deletions
Original file line numberDiff line numberDiff line change
@@ -1,217 +1,22 @@
1-
# UPGRADE FROM 5.x TO 6.0 (WORK IN PROGRESS)
2-
3-
-------------------------
4-
5-
Dotkernel API 5.3 is a minor release. As such, no significant backward compatibility breaks are expected,
6-
with minor backward compatibility breaks being prefixed in this document with `[BC BREAK]`.
7-
This document only covers upgrading from version 5.2.
8-
9-
## Table of Contents
10-
11-
-------------------------
12-
13-
* [Update PHPStan memory limit](#update-phpstan-memory-limit)
14-
* [Update anonymization](#update-anonymization)
15-
* [Update User status and remove isDeleted properties](#update-user-status-and-remove-isdeleted-properties)
16-
* [Update dotkernel/dot-mail to version 5.0](#update-dotkerneldot-mail-to-version-50)
17-
* [Add post install script](#add-post-install-script)
18-
* [Remove post-create-project-cmd](#remove-post-create-project-cmd)
19-
* [Ignore development files on production env](#ignore-development-files-on-production-env)
20-
* [Update security.txt](#update-securitytxt)
21-
* [Update coding standards](#update-coding-standards)
22-
* [Update Qodana configuration](#update-qodana-configuration)
23-
* [Remove laminas/laminas-http](#remove-laminaslaminas-http)
24-
25-
### Update PHPStan memory limit
26-
27-
Following PHPStan's introduction in version 5.2 for the reasons described on the [Dotkernel blog](https://www.dotkernel.com/php-development/static-analysis-replacing-psalm-with-phpstan/) a minor issue has cropped up:
28-
with the default `memory_limit=128M` on our WSL containers, PHPStan runs out of memory
29-
30-
* Add the `--memory-limit 1G` option to the `static-analysis` script found in `composer.json`
31-
> Note that you can set the memory limit to a value of your choosing, with a recommended minimum of 256M
32-
33-
### Update anonymization
34-
35-
By default, Dotkernel API uses "soft delete" for its `User` entities in order to preserve the database entries.
36-
Anonymization is used to make sure any sensitive information is scrubbed from the system, with the `User`'s `identity`, `email`, `firstName` and `lastName` properties being overwritten by a unique placeholder.
37-
Version 5.3 is adding an optional suffix from a configuration file, from where it can be used anywhere in the application.
38-
39-
* Add the `userAnonymizeAppend` key to the returned array in `config/autoload/local.php`, as well as to the distributed`config/autoload/local.php.dist`
40-
41-
```php
42-
'userAnonymizeAppend' => '',
43-
```
44-
45-
* Update the `anonymizeUser` function in `src/User/src/Service/UserService.php` to use the new key
46-
47-
Before:
48-
49-
```php
50-
$user->setIdentity($placeholder) //...
51-
```
52-
53-
After:
54-
55-
```php
56-
$user->setIdentity($placeholder . $this->config['userAnonymizeAppend']) //...
57-
```
58-
59-
> Note that any custom functionality using the old format will require updates
60-
61-
### Update User status and remove isDeleted properties
62-
63-
Up to and including version 5.2, the `User` entity made use of the `UserStatusEnum` to mark the account status (`active` or `inactive`) and marked deleted accounts with the `isDeleted` property.
64-
Starting from version 5.3 the `isDeleted` property has been removed because, by default, there is no use in having both it and the status property.
65-
As such, a new `Deleted` case for `UserStatusEnum` is now used to mark a deleted account and remove the redundancy.
66-
67-
* [BC Break] Remove the `isDeleted` property from the `User` class, alongside all usages, as seen in the [pull request](https://github.com/dotkernel/api/pull/359/files)
68-
* Add a new "deleted" case to `UserStatusEnum`, which is to be used instead of the previous `isDeleted` property
69-
* Update the database and its migrations to reflect the new structure
70-
> The use of "isDeleted" was redundant in the default application, and as such was removed
71-
>
72-
> All default methods are updated, but any custom functionality using "isDeleted" will require refactoring
73-
74-
### Update `dotkernel/dot-mail` to version 5.0
75-
76-
Dotkernel API uses `dotkernel/dot-mail` to handle the mailing service, which in versions older than 5.0 was based on `laminas/laminas-mail`.
77-
Due to the deprecation of `laminas/laminas-mail`, a decision was made to switch `dot-mail` to using `symfony/mailer` starting from version 5.0.
78-
To make the API more future-proof, the upgrade to the new version of `dot-mail` was necessary.
79-
The default usage of the mailer remains unchanged, with the only required updates being to configuration, as described below:
80-
81-
* Bump `dotkernel/dot-mail` to "^5.0" in `composer.json`
82-
* As the mail configuration file is now directly copied from the vendor via [script](#add-post-install-script), remove the existing `config/autoload/mail.global.php[.dist]` file(s)
83-
* Update the content for each of these configuration files to reflect the new structure from [dotkernel/dot-mail](https://github.com/dotkernel/dot-mail/blob/5.0/config/mail.global.php.dist)
84-
* Remove `Laminas\Mail\ConfigProvider::class` from `config/config.php`
85-
> The list of changes can be seen in the [pull request](https://github.com/dotkernel/api/pull/368/files)
86-
>
87-
> You can read more about the reasons for this change on the [Dotkernel blog](https://www.dotkernel.com/dotkernel/replacing-laminas-mail-with-symfony-mailer-in-dot-mail/).
88-
89-
### Remove `post-create-project-cmd`
90-
91-
Installing the API via `composer create-project` is not recommended, and because of this the `post-create-project-cmd` has been removed.
92-
93-
* Remove the `post-create-project-cmd` key found under `scripts` in `composer.json`
94-
95-
```json
96-
"post-create-project-cmd": [
97-
"@development-enable"
98-
],
99-
```
100-
101-
### Add post install script
102-
103-
To make installing the API less of a hassle, a new post installation script was added.
104-
This script generates all the configuration files required by default, leaving the user to simply complete the relevant data.
105-
106-
> Note that the script will not overwrite existing configuration files, preserving any user data
107-
>
108-
> In case the structure of a configuration file needs updating (such as [mail.local.php](#update-dotkerneldot-mail-to-version-50) in this update), simply running the script *will not* make the changes
109-
110-
* Add `bin/composer-post-install-script.php` to automate the post installation copying of distributed configuration files
111-
* Add the following under the `scripts` key in `composer.json`:
112-
113-
```json
114-
"post-update-cmd": [
115-
"php bin/composer-post-install-script.php"
116-
],
117-
```
118-
119-
* Remove the following section from `.github/workflows/codecov.yml` and `.github/workflows/static-analysis.yml`
120-
121-
```yaml
122-
- name: Setup project
123-
run: |
124-
mv config/autoload/local.php.dist config/autoload/local.php
125-
mv config/autoload/mail.global.php.dist config/autoload/mail.global.php
126-
mv config/autoload/local.test.php.dist config/autoload/local.test.php
127-
```
128-
129-
> The command can be manually run via `php bin/composer-post-install-script.php`
130-
131-
### Ignore development files on production env
132-
133-
These tweaks were added to make sure development files remain untouched on production environments.
134-
135-
* Restrict codecov to development mode by changing the following section from `.github/workflows/codecov.yml`:
136-
137-
Before:
138-
139-
```yaml
140-
- name: Install dependencies with composer
141-
run: composer install --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi
142-
```
143-
144-
After:
145-
146-
```yaml
147-
- name: Install dependencies with composer
148-
env:
149-
COMPOSER_DEV_MODE: 1
150-
run: composer install --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi
151-
```
152-
153-
* Edit `.laminas-ci/pre-run.sh` script by changing `echo "Running $COMMAND"` to `echo "Running pre-run $COMMAND"` and delete the following line:
154-
155-
```shell
156-
cp config/autoload/mail.global.php.dist config/autoload/mail.global.php
157-
```
158-
159-
### Update security.txt
160-
161-
Updated the `security.txt` file to define the preferred language of the security team.
162-
It is recommended that the `Expires` tag is also updated if necessary.
163-
164-
* Add the `Preferred-Languages` key to `public/.well-known/security.txt`
165-
> You may include more than one language as comma separated language tags
166-
167-
### Update coding standards
168-
169-
Dotkernel API uses `laminas/laminas-coding-standard` as its baseline ruleset to ensure adherence to PSR-1 and PSR-12.
170-
As this package had a major release, the minimum version the API uses was also bumped.
171-
172-
* Bump `laminas/laminas-coding-standard` to `^3.0` in `composer.json`
173-
* Add the following to `phpcs.xml` to prevent issues with the fully qualified names from `config/config.php`:
174-
175-
```xml
176-
<rule ref="LaminasCodingStandard">
177-
<!-- Exclude rule -->
178-
<exclude name="SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFullyQualifiedName" />
179-
</rule>
180-
```
181-
182-
### Update Qodana configuration
183-
184-
The Qodana code quality workflow has changed its default PHP version to 8.4, which is unsupported by Dotkernel API, resulting in errors.
185-
The issue was fixed by restricting Qodana to the supported PHP versions.
186-
187-
* Update `.github/workflows/qodana_code_quality.yml`, specifying the supported PHP versions by adding the `strategy` key:
188-
189-
```yaml
190-
strategy:
191-
matrix:
192-
php-versions: [ '8.2', '8.3' ]
193-
```
194-
195-
* Update the `php-version` key to restrict Qodana to the newly added `php-versions`
196-
197-
Before:
198-
199-
```yaml
200-
with:
201-
php-version: "${{ matrix.php }}"
202-
```
203-
204-
After:
205-
206-
```yaml
207-
with:
208-
php-version: ${{ matrix.php-versions }}
209-
```
210-
211-
### Remove laminas/laminas-http
212-
213-
Prior to version 5.3, `laminas/laminas-http` was only used in 2 test files to assert if correct status codes were returned.
214-
This dependency was removed, as the usage in tests was replaced with the existing `StatusCodeInterface`.
215-
216-
* Remove `laminas/laminas-http` from `composer.json`
217-
* Replace all uses of `Laminas\Http\Response` with `Fig\Http\Message\StatusCodeInterface` in `AuthorizationMiddlewareTest.php` and `ContentNegotiationMiddlewareTest.php`
1+
# Upgrading from 5.x to 6.0
2+
3+
* Move common logic to Core module [https://github.com/dotkernel/api/pull/358](https://github.com/dotkernel/api/pull/358)
4+
* Refactored Handlers [https://github.com/dotkernel/api/pull/385](https://github.com/dotkernel/api/pull/385)
5+
* Inject `InputFilters` in handlers [https://github.com/dotkernel/api/pull/389](https://github.com/dotkernel/api/pull/389)
6+
* Implemented route grouping [https://github.com/dotkernel/api/pull/391](https://github.com/dotkernel/api/pull/391)
7+
* Service refactoring [https://github.com/dotkernel/api/pull/396](https://github.com/dotkernel/api/pull/396)
8+
* Autogenerate `OAuth2` keys when cloning the project [https://github.com/dotkernel/api/pull/398](https://github.com/dotkernel/api/pull/398)
9+
* Refresh Postman documentation [https://github.com/dotkernel/api/pull/400](https://github.com/dotkernel/api/pull/400)
10+
* Merge `Admin.Core` into `API.Core` [https://github.com/dotkernel/api/pull/401](https://github.com/dotkernel/api/pull/401)
11+
* Implemented `mezzio/mezzio-problem-details` [https://github.com/dotkernel/api/pull/402](https://github.com/dotkernel/api/pull/402)
12+
* Update pre-run.sh [https://github.com/dotkernel/api/pull/404](https://github.com/dotkernel/api/pull/404)
13+
* Update `GetIndexResourceHandler.php` [https://github.com/dotkernel/api/pull/408](https://github.com/dotkernel/api/pull/408)
14+
* Update `local.php.dist` [https://github.com/dotkernel/api/pull/409](https://github.com/dotkernel/api/pull/409)
15+
* Fixed error handling [https://github.com/dotkernel/api/pull/412](https://github.com/dotkernel/api/pull/412)
16+
* Implemented `ResourceProviderMiddleware` and added `ResourceGuardInterface` [https://github.com/dotkernel/api/pull/403](https://github.com/dotkernel/api/pull/403)
17+
* Updated logic in `ContentNegotiationMiddleware` [https://github.com/dotkernel/api/pull/413](https://github.com/dotkernel/api/pull/413)
18+
* `AuthenticationMiddleware` no longer extends `AuthenticationMiddleware` from `mezzio/mezzio-authentication` [https://github.com/dotkernel/api/pull/418](https://github.com/dotkernel/api/pull/418)
19+
* Update `qodana_code_quality.yml` [https://github.com/dotkernel/api/pull/416](https://github.com/dotkernel/api/pull/416)
20+
* Replaced `Twig` with custom templating solution [https://github.com/dotkernel/api/pull/419](https://github.com/dotkernel/api/pull/419)
21+
* Increased `PHPStan` level to 8 [https://github.com/dotkernel/api/pull/421](https://github.com/dotkernel/api/pull/421)
22+
* Split the `/security/token` endpoint into two separate endpoints [https://github.com/dotkernel/api/pull/423](https://github.com/dotkernel/api/pull/423)

0 commit comments

Comments
 (0)