- 1. Presentation
- 2. Prerequisites
- 3. Installation
- 4. Screenshot
- 5. Upload Excel files
- 6. Main technical constraints for the study
- 7. API documentation with Nelmio
- 8. Style Guide
- 9. PHPStorm configuration
- 10. Codacy configuration
- 11. Troubleshooting
- 12. Resources & Inspiration
- 13. Comments, suggestions?
- 14. License
Study of a complete application, with a SPA (Angular) and an API (Symfony), which allows users to connect, and to be able, according to their rights, to import Excel data and modify them online.
Excel Editor SPA |
|
Excel Editor API |
|
Excel Editor Insomnia |
❗
|
Be sure to install the latest version of Docker Compose CLI plugin. |
-
$ git clone [email protected]:jprivet-dev/excel-editor-api
. -
$ cd excel-editor-api
. -
$ make install
: This command will execute the following commands:-
$ make build
: Build or rebuild fresh images if necessary. -
$ make detach
: Create and start containers in detached mode (no logs). -
$ make generate_keypair
: Generate the SSL keys for the JWT authentication. -
$ make fixtures
: Create an admin & an user profils. -
$ make logs
: Show live logs.
-
-
Open your browser on https://localhost/api/doc and Accept the auto-generated TLS certificate.
📎
|
With Excel Editor API, you can use…
|
📎
|
The following steps are based on the Stackoverflow answer Getting Chrome to accept self-signed localhost certificate. |
-
On the page https://localhost/api/doc, click on lock > Certificate Information, then click on Untrusted certificate:
-
In the new dialog, click on the Details tab, and Export button:
-
You will export the
localhost.p7c
file. Click on Save button: -
Go on chrome://settings/certificates then on the Authorities tab, click on Import button and choose the
localhost.p7c
file. -
Check all boxes and click on OK button:
-
You can see org-Caddy Local Authority in the list:
-
Restart Chrome (chrome://restart)
-
Just launch the project with
$ make start
command. -
Open your browser on https://localhost/api/doc.
💡
|
|
The Excel files are uploaded and renamed (with a unique indentifier) in the uploads
folder.
💡
|
You can test and upload the Excel files in the data folder. |
To purge the uploads
folder: $ rm uploads/*.xlsx
.
-
Use of the latest version of Symfony.
-
No API Platform or JMSSerializer: the objective is to study in depth the Serializer Component.
-
Use mainly the code generation commands (Symfony MakerBundle).
-
The project must be dockerized (Symfony Docker).
-
The project must have a consistent and correct code coverage.
📎
|
This project use https://github.com/nelmio/NelmioApiDocBundle |
Open https://localhost/api/doc to see the API documentation.
📎
|
That project (API & SPA) use the camelCase
format for the property names of JSON responses:
{
"thisPropertyIsAnIdentifier": "identifier value"
}
📎
|
In this project, I will not use a listener or subscriber to force all errors into JSON format. As for example with the following subscriber:
namespace App\EventSubscriber;
use Symfony\Component\ErrorHandler\Exception\FlattenException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Serializer\SerializerInterface;
class ExceptionSubscriber implements EventSubscriberInterface
{
public function __construct(private SerializerInterface $serializer)
{
}
public function onKernelException(ExceptionEvent $event): void
{
$response = new JsonResponse();
$exception = $event->getThrowable();
$flattenException = FlattenException::createFromThrowable($exception);
$data = $this->serializer->normalize($flattenException);
$response->setData($data);
// HttpExceptionInterface is a special type of exception that
// holds status code and header details
if ($exception instanceof HttpExceptionInterface) {
$response->setStatusCode($exception->getStatusCode());
$response->headers->replace($exception->getHeaders());
} else {
$response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
}
$event->setResponse($response);
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::EXCEPTION => 'onKernelException',
];
}
}
Instead, I’ll let the user choose the format of the response (HTML, JSON, XML or other) by properly using the Accept
header request:
$ curl https://localhost/api/data --header 'Accept: application/json'
In the SerializerErrorRenderer::render()
of Symfony, a FlattenException
is created from the exception and is passed to the serializer, with the format from the request. Accept: application/json
change the "preferred format" on the request to JSON.
💡
|
In addition, the JSON error will be automatically filled in depending on the environment (dev or prod). |
❗
|
The following configuration are provided for PHPStorm 2022.3.2 |
-
Go on Settings (Ctrl+Alt+S) > PHP.
-
In the PHP Settings dialog, click on … Browse button next to the CLI Interpreter list.
-
In the CLI Interpreters dialog that opens, click on + button and select From Docker, Vagrant, VM, WSL, Remote….
-
In the Configure Remote PHP Interpreter dialog that opens, select "Docker" :
-
In the CLI Interpreters dialog, click on OK button.
-
In the Settings dialog, click on OK or Apply button to validate all.
❗
|
I have a new problem, with PHPStorm 2023.3.1 and 2023.3.2, I did not have on my previous computer: after the configuration, PHP_CodeSniffer & PHP Mess Detector do not work with the Remote PHP Interpreter. Search for a solution in progress… |
-
Go on Settings (Ctrl+Alt+S) > PHP > Quality Tools.
-
Expand the PHP_CodeSniffer area and switch ON the tool.
-
In Configuration, choose By default project interpreter.
-
In Coding standard, select Custom and choose the
phpcs.xml
file of this repository. -
After the configuration of PHP_CodeSniffer, PHPStorm will highlight the problematic lines in the files and can run PHP CS fixer.
-
In the Settings dialog, click on OK or Apply button to validate all.
Include a dependency for squizlabs/php_codesniffer
in the composer.json
file:
{
"require-dev": {
"squizlabs/php_codesniffer": "3.*"
}
}
And update all:
$ make composer c=update # with Makefile
# OR
$ composer update # with .bash_aliases
-
Go on Settings (Ctrl+Alt+S) > PHP > Quality Tools.
-
Expand the PHP Mess Detector area and switch ON the tool.
-
In Configuration, choose By default project interpreter.
-
In Custom rulesets, click on + button and choose the
phpmd.xml
file of this repository. -
In the Settings dialog, click on OK or Apply button to validate all.
$ composer require --dev phpmd/phpmd
📎
|
See https://www.jetbrains.com/help/phpstorm/using-phpunit-framework.html#configure-phpunit-manually |
-
Go on Settings (Ctrl+Alt+S) > PHP > Test Frameworks.
-
Click on + button and select PHPUnit by Remote Interpreter.
-
In PHPUnit by Remote Interpreter, select excel-editor-api-php:latest and click on OK button.
-
In the Settings dialog, click on OK or Apply button to validate all.
For example, in the Project tool window, select the file or folder to run your tests from and choose Run '<file or folder>' from the context menu of the selection:
PhpStorm generates a default run configuration and starts a run test session with it:
📎
|
More information on https://www.jetbrains.com/help/phpstorm/using-phpunit-framework.html#run_phpunit_tests |
💡
|
Set XDEBUG_MODE=coverage before starting the container (see https://github.com/dunglas/symfony-docker/blob/main/docs/xdebug.md).
|
Duplicate CODACY_PROJECT_TOKEN.sh
:
$ cp scripts/CODACY_PROJECT_TOKEN.sh.dist scripts/CODACY_PROJECT_TOKEN.sh
And define the API token CODACY_PROJECT_TOKEN
(see https://app.codacy.com/gh/jprivet-dev/excel-editor-api/settings/coverage).
The file scripts/CODACY_PROJECT_TOKEN.sh
is ignored by Git and imported by scripts/reporter.sh
.
The file scripts/reporter.sh
generates code coverage (a clover.xml
file with PHPUnit) and uploads the coverage reports on Codacy.
Be sure to install the latest version of Docker Compose CLI plugin. With the older generation of docker compose, I had encountered the following error:
$ docker-compose build --pull --no-cache
...
Status: Downloaded newer image for composer:2
---> daa583eddaba
Step 27/31 : COPY composer.* symfony.* ./
COPY failed: no source files were specified
ERROR: Service 'php' failed to build : Build failed
Problem solved with the latest generation:
$ docker compose build --pull --no-cache
-
Dockerization of the project: https://github.com/dunglas/symfony-docker.
{"level":"info","ts":1677857037.9273698,"msg":"warning: \"certutil\" is not available, install \"certutil\" with \"apt install libnss3-tools\" or \"yum install nss-tools\" and try again"}
-
Symfony documentation: https://symfony.com/doc/current/index.html
-
Build a REST API with Symfony: https://openclassrooms.com/fr/courses/7709361-construisez-une-api-rest-avec-symfony
-
Richardson Maturity Model: https://martinfowler.com/articles/richardsonMaturityModel.html
-
Building Restful APIs with Symfony 5 and PHP 8: https://dev.to/hantsy_26/-building-restful-apis-with-symfony-5-and-php-8-1p2e
Feel free to make comments/suggestions to me in the Git issues section.