From a8e6f62e7ccd9ffda7827dd134bcc2c766e98bee Mon Sep 17 00:00:00 2001 From: Vincent Chalamon <407859+vincentchalamon@users.noreply.github.com> Date: Wed, 27 Sep 2023 15:45:26 +0200 Subject: [PATCH 1/2] docs: update docs on README --- README.md | 65 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index b579d8ccc..0e017a4e5 100755 --- a/README.md +++ b/README.md @@ -17,38 +17,42 @@ Try it online at . $ git clone https://github.com/api-platform/demo.git $ cd demo - $ docker compose up -d + $ docker compose up --wait You can now go to https://localhost -## What Can I Find In This Demo? - -This demo application contains several things you may be interested. - -### API Testing - -All entities used in this project are thoroughly tested. Each test class extends -the `ApiTestCase`, which contains specific API assertions. It will make your tests -much more straightforward than using the standard `WebTestCase` provided by Symfony. - -* [Documentation](https://api-platform.com/docs/core/testing/) -* [Code in api/tests/](api/tests) - -### Extensions - -The `Download` collection is restricted to the current user, except for admin users. The Doctrine Query is overridden -using a Doctrine Extension. - -* [Documentation](https://api-platform.com/docs/core/extensions/) -* [Code in api/src/Doctrine/Orm/Extension](api/src/Doctrine/Orm/Extension) - -### State Processors - -The `Download` and `Review` entities require dynamic properties set before save: a date of creation, and a link to the -current user. This is done using State Processors. - -* [Documentation](https://api-platform.com/docs/core/state-processors/) -* [Code in api/src/State/Processor](api/src/State/Processor) +## What Can I Find In This Demo? + +This demo application contains several things you may be interested: + +| Feature | Usage | +|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [Bringing your Own Model](https://api-platform.com/docs/distribution/#bringing-your-own-model) | [Search usage](https://github.com/search?q=repo%3Aapi-platform%2Fdemo+path%3Aapi%2Fsrc+%22%23%5BApiResource%22&type=code) | +| [Model Scaffolding](https://api-platform.com/docs/schema-generator/getting-started/#model-scaffolding) | [Search usage](https://github.com/search?q=repo%3Aapi-platform%2Fdemo+path%3Aapi%2Fsrc+%22%23%5BApiProperty%28types%3A%22&type=code) | +| [Plugging the Persistence System](https://api-platform.com/docs/distribution/#plugging-the-persistence-system) | [Search usage](https://github.com/search?q=repo%3Aapi-platform%2Fdemo+path%3Aapi%2Fsrc+%22%23%5BORM%22&type=code) | +| [Exposing Enums with API Platform](https://les-tilleuls.coop/blog/exposez-vos-enums-avec-api-platform) | [Search usage](api/src/Enum) | +| [Validating Data](https://api-platform.com/docs/distribution/#validating-data) | [Search usage](https://github.com/search?q=repo%3Aapi-platform%2Fdemo+path%3Aapi%2Fsrc+%22%23%5BAssert%22&type=code) | +| [Configuring Operations](https://api-platform.com/docs/core/operations/) | [Search usage](https://github.com/search?q=repo%3Aapi-platform%2Fdemo+path%3Aapi%2Fsrc+%22operations%3A%22&type=code) | +| [Defining Which Operation to Use to Generate the IRI](https://api-platform.com/docs/core/operations/#defining-which-operation-to-use-to-generate-the-iri) | [Search usage](https://github.com/search?q=repo%3Aapi-platform%2Fdemo+path%3Aapi%2Fsrc+%22itemUriTemplate%3A%22&type=code) | +| [Subresources](https://api-platform.com/docs/core/subresources/) | [Search usage](https://github.com/search?q=repo%3Aapi-platform%2Fdemo+path%3Aapi%2Fsrc%2FEntity+%22uriTemplate%3A+%27%2Fbooks%2F%7BbookId%7D%2Freviews%7B._format%7D%27%22&type=code) | +| [Doctrine ORM Filters](https://api-platform.com/docs/core/filters/) | [Search usage](https://github.com/search?q=repo%3Aapi-platform%2Fdemo+path%3Aapi%2Fsrc+%22%23%5BApiFilter%22&type=code) | +| [Creating Custom Doctrine ORM Filters](https://api-platform.com/docs/core/filters/#creating-custom-doctrine-orm-filters) | [Search usage](https://github.com/search?q=repo%3Aapi-platform%2Fdemo+path%3Aapi+%22NameFilter%22+OR+%22app.filter.user.admin.name%22&type=code) | +| [Overriding Default Order](https://api-platform.com/docs/core/default-order/) | [Search usage](https://github.com/search?q=repo%3Aapi-platform%2Fdemo+path%3Aapi%2Fsrc+%22order%3A%22&type=code) | +| [Changing the Number of Items per Page Client-side For a Specific Resource](https://api-platform.com/docs/core/pagination/#changing-the-number-of-items-per-page-client-side-for-a-specific-resource) | [Search usage](https://github.com/search?q=repo%3Aapi-platform%2Fdemo+path%3Aapi%2Fsrc+%22paginationClientItemsPerPage%22&type=code) | +| [Advanced serialization](https://api-platform.com/docs/core/serialization/) | [Search usage](https://github.com/search?q=repo%3Aapi-platform%2Fdemo+path%3Aapi%2Fsrc+%22%23%5BGroups%22&type=code) | +| [User Support](https://api-platform.com/docs/core/user/) | [Search usage](api/src/Entity/User.php) | +| [Custom Doctrine ORM Extension](https://api-platform.com/docs/core/extensions/) | [Search usage](api/src/Doctrine/Orm/Extension) | +| [Custom State Processor](https://api-platform.com/docs/core/state-processors/) | [Search usage](api/src/State/Processor) | +| [Creating Async APIs using the Mercure Protocol](https://api-platform.com/docs/core/mercure/) | [Search usage](https://github.com/search?q=repo%3Aapi-platform%2Fdemo+path%3Aapi%2Fsrc%2FEntity+%22mercure%3A%22&type=code) | +| [Advanced Authentication and Authorization Rules](https://api-platform.com/docs/core/security/) | [Search usage](https://github.com/search?q=repo%3Aapi-platform%2Fdemo+path%3Aapi%2Fsrc%2FEntity+%22security%3A%22+OR+%22securityPostDenormalize%3A%22&type=code) | +| [API Testing](https://api-platform.com/docs/core/testing/) | [Search usage](api/tests) | +| [The Admin](https://api-platform.com/docs/distribution/#the-admin) | [Search usage](pwa/pages/admin) | +| [A Next.js Web App](https://api-platform.com/docs/distribution/#a-nextjs-web-app) | [Search usage](pwa) | +| [Deploying to a Kubernetes Cluster](https://api-platform.com/docs/deployment/kubernetes) | [Search usage](helm/api-platform) | + +> Note: this demo application implements [OpenID Connect Specification Support](https://openid.net/developers/specs/) +> (using [Keycloak](https://www.keycloak.org/)). See [usage in API](api/config/packages/security.yaml) and +> [usage in PWA](pwa/pages/api/auth/%5B...nextauth%5D.tsx). ## Contributing @@ -56,4 +60,5 @@ current user. This is done using State Processors. ## Credits -Created by [Kévin Dunglas](https://dunglas.fr/). Commercial support available at [Les-Tilleuls.coop](https://les-tilleuls.coop/). +Created by [Kévin Dunglas](https://dunglas.fr/). Commercial support available +at [Les-Tilleuls.coop](https://les-tilleuls.coop/). From 1e55f68ae5269ab52bb4335f96b892ba47602d08 Mon Sep 17 00:00:00 2001 From: Vincent Chalamon <407859+vincentchalamon@users.noreply.github.com> Date: Wed, 27 Sep 2023 15:45:37 +0200 Subject: [PATCH 2/2] chore: use constants on serialization contexts --- api/src/Entity/Book.php | 12 +++++++----- api/src/Entity/Bookmark.php | 8 +++++--- api/src/Entity/Review.php | 16 +++++++++------- api/src/Entity/User.php | 6 ++++-- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/api/src/Entity/Book.php b/api/src/Entity/Book.php index 25dee0858..734f58e71 100644 --- a/api/src/Entity/Book.php +++ b/api/src/Entity/Book.php @@ -24,6 +24,8 @@ use Symfony\Bridge\Doctrine\Types\UuidType; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Component\Serializer\Annotation\Groups; +use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; +use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer; use Symfony\Component\Uid\Uuid; use Symfony\Component\Validator\Constraints as Assert; @@ -61,11 +63,11 @@ ), ], normalizationContext: [ - 'groups' => ['Book:read:admin', 'Enum:read'], - 'skip_null_values' => true, + AbstractNormalizer::GROUPS => ['Book:read:admin', 'Enum:read'], + AbstractObjectNormalizer::SKIP_NULL_VALUES => true, ], denormalizationContext: [ - 'groups' => ['Book:write'], + AbstractNormalizer::GROUPS => ['Book:write'], ], // todo waiting for https://github.com/api-platform/core/pull/5844 // collectDenormalizationErrors: true, @@ -80,8 +82,8 @@ new Get(), ], normalizationContext: [ - 'groups' => ['Book:read', 'Enum:read'], - 'skip_null_values' => true, + AbstractNormalizer::GROUPS => ['Book:read', 'Enum:read'], + AbstractObjectNormalizer::SKIP_NULL_VALUES => true, ] )] #[ORM\Entity(repositoryClass: BookRepository::class)] diff --git a/api/src/Entity/Bookmark.php b/api/src/Entity/Bookmark.php index 14bc11c61..b769e7f68 100644 --- a/api/src/Entity/Bookmark.php +++ b/api/src/Entity/Bookmark.php @@ -19,6 +19,8 @@ use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Types\UuidType; use Symfony\Component\Serializer\Annotation\Groups; +use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; +use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer; use Symfony\Component\Uid\Uuid; use Symfony\Component\Validator\Constraints as Assert; @@ -40,14 +42,14 @@ ), ], normalizationContext: [ - 'groups' => ['Bookmark:read'], - 'skip_null_values' => true, + AbstractNormalizer::GROUPS => ['Bookmark:read'], + AbstractObjectNormalizer::SKIP_NULL_VALUES => true, IriTransformerNormalizer::CONTEXT_KEY => [ 'book' => '/books/{id}{._format}', ], ], denormalizationContext: [ - 'groups' => ['Bookmark:write'], + AbstractNormalizer::GROUPS => ['Bookmark:write'], ], // todo waiting for https://github.com/api-platform/core/pull/5844 // collectDenormalizationErrors: true, diff --git a/api/src/Entity/Review.php b/api/src/Entity/Review.php index 1c78b3aab..229115776 100644 --- a/api/src/Entity/Review.php +++ b/api/src/Entity/Review.php @@ -24,6 +24,8 @@ use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Types\UuidType; use Symfony\Component\Serializer\Annotation\Groups; +use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; +use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer; use Symfony\Component\Uid\Uuid; use Symfony\Component\Validator\Constraints as Assert; @@ -66,11 +68,11 @@ 'book' => '/admin/books/{id}{._format}', 'user' => '/admin/users/{id}{._format}', ], - 'skip_null_values' => true, - 'groups' => ['Review:read', 'Review:read:admin'], + AbstractObjectNormalizer::SKIP_NULL_VALUES => true, + AbstractNormalizer::GROUPS => ['Review:read', 'Review:read:admin'], ], denormalizationContext: [ - 'groups' => ['Review:write', 'Review:write:admin'], + AbstractNormalizer::GROUPS => ['Review:write', 'Review:write:admin'], ], // todo waiting for https://github.com/api-platform/core/pull/5844 // collectDenormalizationErrors: true, @@ -101,7 +103,7 @@ processor: ReviewPersistProcessor::class, provider: CreateProvider::class, itemUriTemplate: '/books/{bookId}/reviews/{id}{._format}', - validationContext: ['groups' => ['Default', 'Review:create']] + validationContext: [AbstractNormalizer::GROUPS => ['Default', 'Review:create']] ), new Patch( uriTemplate: '/books/{bookId}/reviews/{id}{._format}', @@ -129,11 +131,11 @@ 'book' => '/books/{id}{._format}', 'user' => '/users/{id}{._format}', ], - 'skip_null_values' => true, - 'groups' => ['Review:read'], + AbstractObjectNormalizer::SKIP_NULL_VALUES => true, + AbstractNormalizer::GROUPS => ['Review:read'], ], denormalizationContext: [ - 'groups' => ['Review:write'], + AbstractNormalizer::GROUPS => ['Review:write'], ], // todo waiting for https://github.com/api-platform/core/pull/5844 // collectDenormalizationErrors: true diff --git a/api/src/Entity/User.php b/api/src/Entity/User.php index bc84bf169..237b01520 100644 --- a/api/src/Entity/User.php +++ b/api/src/Entity/User.php @@ -14,6 +14,8 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Serializer\Annotation\Groups; +use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; +use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer; use Symfony\Component\Uid\Uuid; /** @@ -41,8 +43,8 @@ ), ], normalizationContext: [ - 'groups' => ['User:read'], - 'skip_null_values' => true, + AbstractNormalizer::GROUPS => ['User:read'], + AbstractObjectNormalizer::SKIP_NULL_VALUES => true, ] )] #[ORM\Entity(repositoryClass: UserRepository::class)]