From 7a433f89db7eb7db2102c88ca54a88061d1ba0f2 Mon Sep 17 00:00:00 2001 From: mehdi Date: Wed, 28 Feb 2024 10:54:09 +0100 Subject: [PATCH 01/22] update create-client doc for react --- create-client/react.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/create-client/react.md b/create-client/react.md index 5075cbdc2c4..ba183eb8a2e 100644 --- a/create-client/react.md +++ b/create-client/react.md @@ -9,14 +9,12 @@ from the ecosystem: * [React Router](https://reactrouter.com/) * [React Hook Form](https://react-hook-form.com/) -It is designed to generate code that works seamlessly with [Facebook's Create React App](https://create-react-app.dev/). - ## Install Bootstrap a React application: ```console -npm init react-app -- --template typescript my-app +npm create vite@latest my-app -- --template react-ts cd my-app ``` @@ -35,7 +33,7 @@ npm install bootstrap font-awesome Finally, start the integrated web server: ```console -npm run start +npm run dev ``` ## Generating a Web App @@ -54,7 +52,7 @@ The code has been generated, and is ready to be executed! Register the reducers and the routes: ```typescript -// client/src/index.tsx +// my-app/src/main.tsx import React from 'react'; import ReactDOM from 'react-dom/client'; import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; @@ -74,9 +72,9 @@ root.render( - + }/> {/* Add your routes here */} -

Not Found

} /> + } />
From 1ab12e2b576430104e93bd229f72cbf2a3b721e1 Mon Sep 17 00:00:00 2001 From: Bredillet Thomas Date: Sun, 3 Mar 2024 18:41:58 +0100 Subject: [PATCH 02/22] Fix typo on state processors doc (#1913) --- core/state-processors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/state-processors.md b/core/state-processors.md index 3d2ddc0a04b..7149b994207 100644 --- a/core/state-processors.md +++ b/core/state-processors.md @@ -80,7 +80,7 @@ Here is an implementation example which uses [Symfony Mailer](https://symfony.co ```php Date: Mon, 11 Mar 2024 13:05:02 +0100 Subject: [PATCH 03/22] Fixed readinessProbe tabs (#1915) --- deployment/kubernetes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deployment/kubernetes.md b/deployment/kubernetes.md index 9d5e571f340..415385ce64b 100644 --- a/deployment/kubernetes.md +++ b/deployment/kubernetes.md @@ -223,6 +223,6 @@ The `readinessProbe` and the `livenessProble` can not use the default `docker-he readinessProbe: exec: command: ["/bin/sh", "-c", "/bin/ps -ef | grep messenger:consume | grep -v grep"] - initialDelaySeconds: 120 - periodSeconds: 3 + initialDelaySeconds: 120 + periodSeconds: 3 ``` From a449c6e245bd2b521e604fbf41fb31626bbb48a5 Mon Sep 17 00:00:00 2001 From: Mat <7613997+Ak1r0@users.noreply.github.com> Date: Sun, 17 Mar 2024 02:42:44 +0100 Subject: [PATCH 04/22] Fix command line to generate public and private keys using lexik:jwt:generate-keypair --- core/jwt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/jwt.md b/core/jwt.md index f7a0d5644fc..593f0bb4e47 100644 --- a/core/jwt.md +++ b/core/jwt.md @@ -23,7 +23,7 @@ Then we need to generate the public and private keys used for signing JWT tokens ```console docker compose exec php sh -c ' set -e - apk add openssl + apt-get install openssl php bin/console lexik:jwt:generate-keypair setfacl -R -m u:www-data:rX -m u:"$(whoami)":rwX config/jwt setfacl -dR -m u:www-data:rX -m u:"$(whoami)":rwX config/jwt From 06f03d14a3216d6e8a68e67587db7e083144ebba Mon Sep 17 00:00:00 2001 From: soyuka Date: Mon, 18 Mar 2024 12:18:40 +0100 Subject: [PATCH 05/22] graphql: fix code selector --- core/graphql.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/core/graphql.md b/core/graphql.md index 85fa68d6205..801617320c5 100644 --- a/core/graphql.md +++ b/core/graphql.md @@ -318,7 +318,7 @@ Now that your resolver is created and registered, you can configure your custom In your resource, add the following: -[codeselector] + ```php ```php ```php ```php ```php ```php ```php ```php ```php ```php ```php ```php -[codeselector] + ```php ```php ```php ```php Date: Mon, 18 Mar 2024 12:46:39 +0100 Subject: [PATCH 06/22] typo on subresources.md (#1912) missing line break was causing formatting error on https://api-platform.com/docs/core/subresources/ --- core/subresources.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core/subresources.md b/core/subresources.md index 4723b139acf..cc3905b21f2 100644 --- a/core/subresources.md +++ b/core/subresources.md @@ -109,6 +109,7 @@ To make things work, API Platform needs information about how to retrieve the `A the `Question`, this is done by configuring the `uriVariables`: + ```php Date: Mon, 18 Mar 2024 13:02:24 +0100 Subject: [PATCH 07/22] Add \Stringable as new list item (#1922) --- core/identifiers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/identifiers.md b/core/identifiers.md index 1b9d9231889..03c2ea9eec5 100644 --- a/core/identifiers.md +++ b/core/identifiers.md @@ -204,4 +204,4 @@ API Platform supports the following identifier types: - `\Ramsey\Uuid\Uuid` (see [UuidNormalizer](https://github.com/api-platform/core/blob/main/src/RamseyUuid/UriVariableTransformer/UuidUriVariableTransformer.php)) - `\Symfony\Component\Uid\Ulid` (see [UlidNormalizer](https://github.com/api-platform/core/blob/main/src/Symfony/UriVariableTransformer/UlidUriVariableTransformer.php)) - `\Symfony\Component\Uid\Uuid` (see [UuidNormalizer](https://github.com/api-platform/core/blob/main/src/Symfony/UriVariableTransformer/UuidUriVariableTransformer.php)) - `\Stringable` (essential when using composite identifiers from related resource classes) +- `\Stringable` (essential when using composite identifiers from related resource classes) From 85f5b070c4ffcf78b63c501e1d2314150097b6bf Mon Sep 17 00:00:00 2001 From: darkweak Date: Mon, 18 Mar 2024 13:02:53 +0100 Subject: [PATCH 08/22] feat(performance): add Souin setup to the documentation (#1914) --- core/performance.md | 62 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/core/performance.md b/core/performance.md index 68d00907372..94d0eb3f719 100644 --- a/core/performance.md +++ b/core/performance.md @@ -20,6 +20,63 @@ cache. This ensures that the content served will always be fresh, because the ca most specific cases such as the invalidation of collections when a document is added or removed or for relationships and inverse relations is built-in. +### Integrations + +#### Built-in Caddy HTTP cache + +The API Platform distribution relies on the [Caddy web server](https://caddyserver.com) which provide an official HTTP cache module called [cache-handler](https://github.com/caddyserver/cache-handler), that is based on [Souin](https://github.com/darkweak/souin). + +The integration using the cache-handler is quite simple. You juste have to update the `api/Dockerfile` to build your caddy instance with the HTTP cache + +```diff +# Versions +-FROM dunglas/frankenphp:1-php8.3 AS frankenphp_upstream + ++FROM dunglas/frankenphp:latest-builder AS builder ++COPY --from=caddy:builder /usr/bin/xcaddy /usr/bin/xcaddy ++ ++ENV CGO_ENABLED=1 XCADDY_SETCAP=1 XCADDY_GO_BUILD_FLAGS="-ldflags \"-w -s -extldflags '-Wl,-z,stack-size=0x80000'\"" ++RUN xcaddy build \ ++ --output /usr/local/bin/frankenphp \ ++ --with github.com/dunglas/frankenphp=./ \ ++ --with github.com/dunglas/frankenphp/caddy=./caddy/ \ ++ --with github.com/dunglas/mercure/caddy \ ++ --with github.com/dunglas/vulcain/caddy \ ++ # Use --with github.com/darkweak/souin for the latest improvements ++ --with github.com/caddyserver/cache-handler ++ ++FROM dunglas/frankenphp:latest AS frankenphp_upstream ++COPY --from=builder --link /usr/local/bin/frankenphp /usr/local/bin/frankenphp +``` + +Update your Caddyfile with the following configuration: +```caddyfile +{ + order cache before rewrite + ... + cache { + api { + souin + } + } +} +``` +This will tell to caddy to use the HTTP cache and activate the tag based invalidation API. You can refer to the [cache-handler documentation](https://github.com/caddyserver/cache-handler) or the [souin website documentation](https://docs.souin.io) to learn how to configure the HTTP cache server. + +Setup the HTTP cache invalidation in your API Platform project +```yaml +api_platform: + http_cache: + invalidation: + # We assume that your API can reach your caddy instance by the hostname http://caddy. + # The endpoint /souin-api/souin is the default path to the invalidation API. + urls: [ 'http://caddy/souin-api/souin' ] + purger: api_platform.http_cache.purger.souin +``` +And voilà, you have a fully working HTTP cache with it's own invalidation API. + +#### Varnish + Integration with Varnish and Doctrine ORM is shipped with the core library. Add the following configuration to enable the cache invalidation system: @@ -38,8 +95,9 @@ api_platform: vary: ['Content-Type', 'Authorization', 'Origin'] ``` -Support for reverse proxies other than Varnish can be added by implementing the `ApiPlatform\HttpCache\PurgerInterface`. -Two purgers are available, the http tags (`api_platform.http_cache.purger.varnish.ban`) or the surrogate key implementation +## Configuration +Support for reverse proxies other than Varnish or Caddy with the HTTP cache module can be added by implementing the `ApiPlatform\HttpCache\PurgerInterface`. +Three purgers are available, the built-in caddy http cache purger (`api_platform.http_cache.purger.souin`), the http tags (`api_platform.http_cache.purger.varnish.ban`), the surrogate key implementation (`api_platform.http_cache.purger.varnish.xkey`). You can specify the implementation using the `purger` configuration node, for example to use the xkey implementation: From ad6c3eb49c00dac60abc8487514b9d5a139b6cdc Mon Sep 17 00:00:00 2001 From: Damsito <60774219+Damsito@users.noreply.github.com> Date: Mon, 18 Mar 2024 13:03:13 +0100 Subject: [PATCH 09/22] Update file-upload.md (#1909) Update normalization with the symfony 7 normalizer interface + update test --- core/file-upload.md | 80 +++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 35 deletions(-) diff --git a/core/file-upload.md b/core/file-upload.md index 12c89330ac9..7014d0b01bf 100644 --- a/core/file-upload.md +++ b/core/file-upload.md @@ -169,44 +169,53 @@ A [normalizer](serialization.md#normalization) could be used to set the `content ```php contentUrl = $this->storage->resolveUri($object, 'file'); + $object->contentUrl = $this->storage->resolveUri($object, 'file'); - return $this->normalizer->normalize($object, $format, $context); - } + return $this->normalizer->normalize($object, $format, $context); + } - public function supportsNormalization($data, ?string $format = null, array $context = []): bool - { - if (isset($context[self::ALREADY_CALLED])) { - return false; - } + public function supportsNormalization($data, ?string $format = null, array $context = []): bool + { - return $data instanceof MediaObject; + if (isset($context[self::ALREADY_CALLED])) { + return false; } + + return $data instanceof MediaObject; + } + + public function getSupportedTypes(?string $format): array + { + return [ + MediaObject::class => true, + ]; + } } + ``` ### Making a Request to the `/media_objects` Endpoint @@ -314,25 +323,26 @@ class MediaObjectTest extends ApiTestCase public function testCreateAMediaObject(): void { - $file = new UploadedFile('fixtures/files/image.png', 'image.png'); + // The file "image.jpg" is the folder fixtures which is in the project dir + $file = new UploadedFile(__DIR__ . '/../fixtures/image.jpg', 'image.jpg'); $client = self::createClient(); - $client->request('POST', '/media_objects', [ - 'headers' => ['Content-Type' => 'multipart/form-data'], - 'extra' => [ - // If you have additional fields in your MediaObject entity, use the parameters. - 'parameters' => [ - 'title' => 'My file uploaded', - ], - 'files' => [ - 'file' => $file, - ], - ] + $client->request('POST', 'http://localhost:8888/api/media_objects', [ + 'headers' => ['Content-Type' => 'multipart/form-data'], + 'extra' => [ + // If you have additional fields in your MediaObject entity, use the parameters. + 'parameters' => [ + // 'title' => 'title' + ], + 'files' => [ + 'file' => $file, + ], + ] ]); $this->assertResponseIsSuccessful(); $this->assertMatchesResourceItemJsonSchema(MediaObject::class); $this->assertJsonContains([ - 'title' => 'My file uploaded', + // 'title' => 'My file uploaded', ]); } } From 7cc70df8cca122a6a8a3c873b25ce1ea8da37374 Mon Sep 17 00:00:00 2001 From: MaximumP Date: Mon, 18 Mar 2024 13:04:10 +0100 Subject: [PATCH 10/22] Update Caddyfile path in docs (#1908) * Update index.md Adapted path to Caddyfile * Update caddy.md Adapted path to Caddyfile --- distribution/caddy.md | 2 +- distribution/index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/distribution/caddy.md b/distribution/caddy.md index b6fa7a22f69..af0e3da931a 100644 --- a/distribution/caddy.md +++ b/distribution/caddy.md @@ -19,7 +19,7 @@ For instance, when you create your own Symfony controllers serving HTML pages, or when using bundles such as EasyAdmin or SonataAdmin. To do so, you have to tweak the rules used to route the requests. -Open `api-platform/api/docker/caddy/Caddyfile` and modify the expression. +Open `api-platform/api/frankenphp/Caddyfile` and modify the expression. You can use [any CEL (Common Expression Language) expression](https://caddyserver.com/docs/caddyfile/matchers#expression) supported by Caddy. For instance, if you want to route all requests to a path starting with `/admin` to the API, modify the existing expression like this: diff --git a/distribution/index.md b/distribution/index.md index 4b4e16912cf..c91cac6a5e7 100644 --- a/distribution/index.md +++ b/distribution/index.md @@ -201,7 +201,7 @@ You'll need to add a security exception in your browser to accept the self-signe for this container when installing the framework. Later you will probably replace this welcome screen by the homepage of your Next.js application. If you don't plan to create -a Progressive Web App, you can remove the `pwa/` directory as well as the related lines in `docker-compose*.yml` and in `api/docker/caddy/Caddyfile` (don't do it +a Progressive Web App, you can remove the `pwa/` directory as well as the related lines in `docker-compose*.yml` and in `api/frankenphp/Caddyfile` (don't do it now, we'll use this container later in this tutorial). Click on the "API" button, or go to `https://localhost/docs/`: From 2b0a32c023579e1ee1fb06883f9fc1b1c596525d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc?= Date: Mon, 18 Mar 2024 13:05:24 +0100 Subject: [PATCH 11/22] doc(UploadFile): fix #1893 doc of Uploading to an Existing Resource with its Fields (#1897) - Adding the getSupport method to make the class compatible with Symfony 7. - Switching from UploadedFile to File for consistency with Vich. Co-authored-by: Kinhelm --- core/file-upload.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/core/file-upload.md b/core/file-upload.md index 7014d0b01bf..b0b30e57983 100644 --- a/core/file-upload.md +++ b/core/file-upload.md @@ -462,19 +462,28 @@ We also need to make sure the field containing the uploaded file is not denormal namespace App\Serializer; -use Symfony\Component\HttpFoundation\File\UploadedFile; +use Symfony\Component\HttpFoundation\File\File; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; final class UploadedFileDenormalizer implements DenormalizerInterface { - public function denormalize($data, string $type, string $format = null, array $context = []): UploadedFile + public function denormalize($data, string $type, string $format = null, array $context = []): File { return $data; } - public function supportsDenormalization($data, $type, $format = null): bool + public function supportsDenormalization($data, $type, $format = null, array $context = []): bool + { + return $data instanceof File; + } + + public function getSupportedTypes(?string $format): array { - return $data instanceof UploadedFile; + return [ + 'object' => null, + '*' => false, + File::class => true, + ]; } } ``` From ac4a8645e5f596a83e36c23d38450af2f6f6c847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Suwi=C5=84ski?= Date: Tue, 19 Mar 2024 08:24:31 +0100 Subject: [PATCH 12/22] admin resolves semantincs by @id (iris) --- admin/schema.org.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/schema.org.md b/admin/schema.org.md index 61769e2e53c..feb76d1b561 100644 --- a/admin/schema.org.md +++ b/admin/schema.org.md @@ -18,7 +18,7 @@ To configure which property should be shown to represent your entity, map the pr // api/src/Entity/Person.php ... -#[ApiProperty(types: ["https://schema.org/name"])] +#[ApiProperty(iris: ["https://schema.org/name"])] private $name; ... From 2782d9494041a210bdef1b6200da4b69c43004f6 Mon Sep 17 00:00:00 2001 From: Joni Halme Date: Tue, 26 Mar 2024 13:23:42 +0200 Subject: [PATCH 13/22] Fix typo in validation.md --- core/validation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/validation.md b/core/validation.md index 7676328d599..407ae9fd64d 100644 --- a/core/validation.md +++ b/core/validation.md @@ -208,7 +208,7 @@ use ApiPlatform\Metadata\ApiResource; use Symfony\Component\Validator\Constraints as Assert; #[ApiResource( - validationContext: ['groups' => [Book::class, 'validationGroups'] + validationContext: ['groups' => [Book::class, 'validationGroups']] )] class Book { From 9c6d206626e8777a783330e85957d488e2dc1283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Monterisi?= Date: Fri, 29 Mar 2024 17:34:20 +0100 Subject: [PATCH 14/22] Remove Foundry from alternatives It's not an alternative anymore since it's the snippets. --- distribution/testing.md | 1 - 1 file changed, 1 deletion(-) diff --git a/distribution/testing.md b/distribution/testing.md index 78dc2bbc86c..51a00f44421 100644 --- a/distribution/testing.md +++ b/distribution/testing.md @@ -372,7 +372,6 @@ The API Platform Demo [contains a CD workflow](https://github.com/api-platform/d You may also be interested in these alternative testing tools (not included in the API Platform distribution): * [Hoppscotch](https://docs.hoppscotch.io/features/tests), create functional test for your API -* [Foundry](https://github.com/zenstruck/foundry), a modern fixtures library that will replace Alice as the recommended fixtures library soon; * [Hoppscotch](https://docs.hoppscotch.io/documentation/features/rest-api-testing/), create functional test for your API Platform project using a nice UI, benefit from its Swagger integration and run tests in the CI using [the command-line tool](https://docs.hoppscotch.io/cli); * [Behat](https://behat.org), a From 84771e760b177c9ae4b264c322a9d80f6f726e4c Mon Sep 17 00:00:00 2001 From: Jems <5523410+J3m5@users.noreply.github.com> Date: Wed, 3 Apr 2024 17:30:48 +0200 Subject: [PATCH 15/22] Add instructions for building Next.js client with SSG locally in Docker Compose (#1918) * docs(deployment/docker-compose.md): Add a section Building Next.js client locally with SSG Added detailed instructions for building a Next.js client with Static Site Generation (SSG) in a Docker Compose environment. The steps include adjustments to the compose.prod.yaml file, starting the php service container, optional creation of a .env file for the Next.js client, building the pwa service, and finally bringing up the full project. This setup ensures the Next.js client can access the API at build time for static page generation. * docs(create-client/nextjs.md): Generating a production build locally with docker compose Updated the Next.js documentation to include instructions for generating a production build locally using Docker Compose. The update provides a link to the detailed steps in the Docker Compose deployment guide. * docs(deployment/kubernetes.ms): Added Docker build command for SSG in Kubernetes doc Added optional Docker build command for SSG projects in Kubernetes doc. This command allows the PWA to access a locally running API during the build process, useful for generating static pages at build time. * docs(deployement/docker-compose): add a step to override the php env variables To ensure TRUSTED_HOSTS and MERCURE_PUBLIC_URL remain valid when altering SERVER_NAME to use an HTTP scheme or include a port, these variables must be overridden. This adjustment accommodates configurations where SERVER_NAME deviates from the standard HTTPS format or includes port specifications. * docs(deployement/docker-compose): adapt docs for variables update --------- Co-authored-by: JH --- create-client/nextjs.md | 4 +++ deployment/docker-compose.md | 69 ++++++++++++++++++++++++++++++++++-- deployment/kubernetes.md | 18 ++++++---- 3 files changed, 83 insertions(+), 8 deletions(-) diff --git a/create-client/nextjs.md b/create-client/nextjs.md index 58301befe78..4320c89ad7f 100644 --- a/create-client/nextjs.md +++ b/create-client/nextjs.md @@ -98,6 +98,10 @@ yarn dev Go to `http://localhost:3000/books/` to start using your app. +## Generating a production build locally with docker compose + +If you want to generate a production build locally with docker compose, follow [these instructions](../deployment/docker-compose.md) + ## Screenshots ![List](images/nextjs/create-client-nextjs-list.png) diff --git a/deployment/docker-compose.md b/deployment/docker-compose.md index 364161d0b7d..4b7798336d1 100644 --- a/deployment/docker-compose.md +++ b/deployment/docker-compose.md @@ -89,8 +89,10 @@ Go to `https://your-domain-name.example.com` and enjoy! Alternatively, if you don't want to expose an HTTPS server but only an HTTP one, run the following command: -```console -SERVER_NAME=:80 \ +```bash +SERVER_NAME=http://localhost \ +MERCURE_PUBLIC_URL=http://localhost/.well-known/mercure \ +TRUSTED_HOSTS='^localhost|php$' \ APP_SECRET=ChangeMe \ CADDY_MERCURE_JWT_SECRET=ChangeThisMercureHubJWTSecretKey \ docker compose -f -compose.yaml -f compose.prod.yaml up --wait @@ -114,3 +116,66 @@ As a shortcut, `private_ranges` may be configured to trust all private IP ranges + trusted_proxies private_ranges +} ``` + +## Building Next.js client locally with SSG + +When deploying API Platform with Docker Compose and you need to build a Next.js client that utilizes Static Site Generation (SSG), a specific setup is required. +This setup ensures the Next.js client can access the API at build time to generate static pages. + +### Configuration Steps + +#### 1. Adjust the compose.prod.yaml file + +Modify the pwa service to ensure network communication between the pwa and php services during the build: + +```yaml + pwa: + build: + context: ./pwa + target: prod + network: host + extra_hosts: + - php=127.0.0.1 +``` + +#### 2. Build and start the php service + +Begin by starting the php service container: + +```bash +SERVER_NAME=http://localhost \ +MERCURE_PUBLIC_URL=http://localhost/.well-known/mercure \ +TRUSTED_HOSTS='^localhost|php$' \ +APP_SECRET=!ChangeMe! \ +CADDY_MERCURE_JWT_SECRET=ChangeThisMercureHubJWTSecretKey \ +POSTGRES_PASSWORD=!ChangeMe! \ +docker compose -f compose.yaml -f compose.prod.yaml up -d --build --wait php +``` + +#### 3. Optional: Env file with create-client + +If your are using the [create-client](../create-client/nextjs.md) generator inside your Next.js client, you need to create a `.env` file in the `pwa` directory with the `NEXT_PUBLIC_ENTRYPOINT` environment variable to ensure the Next.js client knows where to find the API: + +```dotenv +NEXT_PUBLIC_ENTRYPOINT=http://php +``` + +#### 4. Build the pwa service + +```bash +docker compose -f compose.yaml -f compose.prod.yaml build pwa +``` + +#### 5. Finally, bring up the full project + +```bash +SERVER_NAME=http://localhost \ +MERCURE_PUBLIC_URL=http://localhost/.well-known/mercure \ +TRUSTED_HOSTS='^localhost|php$' \ +APP_SECRET=!ChangeMe! \ +CADDY_MERCURE_JWT_SECRET=ChangeThisMercureHubJWTSecretKey \ +POSTGRES_PASSWORD=!ChangeMe! \ +docker compose -f compose.yaml -f compose.prod.yaml up -d --wait +``` + +These steps ensure the Next.js client can statically generate pages by accessing the API during the build process. diff --git a/deployment/kubernetes.md b/deployment/kubernetes.md index 415385ce64b..b72316304f0 100644 --- a/deployment/kubernetes.md +++ b/deployment/kubernetes.md @@ -44,6 +44,12 @@ docker build -t gcr.io/test-api-platform/caddy:0.1.0 -t gcr.io/test-api-platform docker build -t gcr.io/test-api-platform/pwa:0.1.0 -t gcr.io/test-api-platform/pwa:latest pwa --target prod ``` +Optional: If your pwa project use Static Site Generation (SSG) and you need to build it against the API running locally, you can build the pwa with the command below. + +```bash +docker build -t gcr.io/test-api-platform/pwa:0.1.0 -t gcr.io/test-api-platform/pwa:latest pwa --target prod --network=host --add-host php=127.0.0.1 +``` + #### 2. Push your images to your Docker registry ```console @@ -53,12 +59,12 @@ docker push gcr.io/test-api-platform/caddy docker push gcr.io/test-api-platform/pwa ``` -Optional push the version images: +Optional: push the version images: ```console -docker push gcr.io/test-api-platform/php:0.1.0 -docker push gcr.io/test-api-platform/caddy:0.1.0 -docker push gcr.io/test-api-platform/pwa:0.1.0 +docker push gcr.io/test-api-platform/php:0.1.0 +docker push gcr.io/test-api-platform/caddy:0.1.0 +docker push gcr.io/test-api-platform/pwa:0.1.0 ``` The result should look similar to these images. @@ -114,7 +120,7 @@ Replace the values with the image parameters from the stage above. The parameter `php.appSecret` is the `AppSecret` from ./.env Fill the rest of the values with the correct settings. For available options see /helm/api-platform/values.yaml. -If you want a test deploy you can set corsAllowOrigin='*' +If you want a test deploy you can set corsAllowOrigin='\*' After a successful installation, there is a message at the end. You can copy these commands and execute them to set a port-forwarding and @@ -166,7 +172,7 @@ You can upgrade with the same command from the installation and pass all paramet ### 2. Use :latest tags Infos about [best practices for tagging images for Kubernetes](https://kubernetes.io/docs/concepts/containers/images/) -You have to use the *.image.pullPolicy=Always see the last 3 parameters. +You have to use the \*.image.pullPolicy=Always see the last 3 parameters. ```console PHP_POD=$(kubectl --namespace=bar get pods -l app=php -o jsonpath="{.items[0].metadata.name}") From eb85fcf1a5c1fa6b1bf435c9768468bc712ba26d Mon Sep 17 00:00:00 2001 From: simon511000 Date: Wed, 17 Apr 2024 14:28:25 +0200 Subject: [PATCH 16/22] Add missing private to mailer property --- core/state-processors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/state-processors.md b/core/state-processors.md index 7149b994207..c8c6e5277fc 100644 --- a/core/state-processors.md +++ b/core/state-processors.md @@ -101,7 +101,7 @@ final class UserProcessor implements ProcessorInterface private ProcessorInterface $persistProcessor, #[Autowire(service: 'api_platform.doctrine.orm.state.remove_processor')] private ProcessorInterface $removeProcessor, - MailerInterface $mailer, + private MailerInterface $mailer, ) { } From 665d32f480dd84b1d9914d617b83b8997eb458a3 Mon Sep 17 00:00:00 2001 From: mboultoureau Date: Thu, 18 Apr 2024 11:19:04 +0200 Subject: [PATCH 17/22] fix: autowire item provider --- core/state-providers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/state-providers.md b/core/state-providers.md index 7f6ad3d772b..b5de9769c54 100644 --- a/core/state-providers.md +++ b/core/state-providers.md @@ -153,7 +153,7 @@ use Symfony\Component\DependencyInjection\Attribute\Autowire; final class BookRepresentationProvider implements ProviderInterface { public function __construct( - #[Autowire('api_platform.doctrine.orm.state.item_provider')] + #[Autowire(service: 'api_platform.doctrine.orm.state.item_provider')] private ProviderInterface $itemProvider, ) { From 0249fa835120642427102c7f83f61eaabee0434c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20H=C3=A9lias?= Date: Mon, 29 Apr 2024 10:55:10 +0200 Subject: [PATCH 18/22] fix: Use NormalizerInterface --- core/serialization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/serialization.md b/core/serialization.md index 7a22f360f3a..20da77f4f2d 100644 --- a/core/serialization.md +++ b/core/serialization.md @@ -911,11 +911,11 @@ Here is an example: namespace App\Serializer; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface; use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface; use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait; +use Symfony\Component\Serializer\Normalizer\NormalizerInterface; -class BookAttributeNormalizer implements ContextAwareNormalizerInterface, NormalizerAwareInterface +class BookAttributeNormalizer implements NormalizerInterface, NormalizerAwareInterface { use NormalizerAwareTrait; From c957aa94bec73880a1206154a4b68a0b39f6b076 Mon Sep 17 00:00:00 2001 From: Nozarashi Date: Fri, 19 Apr 2024 21:13:23 +0200 Subject: [PATCH 19/22] docs: remove enable_authenticator_manager option --- core/jwt.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/jwt.md b/core/jwt.md index 593f0bb4e47..a8f49813ad6 100644 --- a/core/jwt.md +++ b/core/jwt.md @@ -64,8 +64,6 @@ security: password_hashers: App\Entity\User: 'auto' - # https://symfony.com/doc/current/security/authenticator_manager.html - enable_authenticator_manager: true # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers providers: # used to reload user from session & other features (e.g. switch_user) From e3a1488768d2a9fd7c5487018992dc83e7efc330 Mon Sep 17 00:00:00 2001 From: matthieu-delisle <94405658+matthieu-delisle@users.noreply.github.com> Date: Mon, 29 Apr 2024 07:23:19 -0400 Subject: [PATCH 20/22] kubernetes: Messenger with FrankenPHP (#1939) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs(kubernetes) : Adding instruction for the messenger queue with FrankenPHP image The readinessProbe and livenessProbe suggested in the documentation failed because the /bin/ps wasn't installed on the Docker Image. * Update deployment/kubernetes.md Co-authored-by: Kévin Dunglas * Update kubernetes.md * Update kubernetes.md * lint --------- Co-authored-by: Kévin Dunglas --- deployment/kubernetes.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/deployment/kubernetes.md b/deployment/kubernetes.md index b72316304f0..fb8255f77d4 100644 --- a/deployment/kubernetes.md +++ b/deployment/kubernetes.md @@ -225,10 +225,31 @@ commandArgs: ['messenger:consume', 'async', '--memory-limit=100M'] The `readinessProbe` and the `livenessProble` can not use the default `docker-healthcheck` but should test if the command is running. +First, make sure to install the `/bin/ps` binary, otherwise the `readinessProbe` and `livenessProbe` will fail: + + + +```patch +# api/Dockerfile + +RUN apt-get update && apt-get install --no-install-recommends -y \ ++ procps \ +# ... +``` + + + +Then, update the probes: + ```yaml readinessProbe: exec: command: ["/bin/sh", "-c", "/bin/ps -ef | grep messenger:consume | grep -v grep"] initialDelaySeconds: 120 periodSeconds: 3 +livenessProbe: + exec: + command: ["/bin/sh", "-c", "/bin/ps -ef | grep messenger:consume | grep -v grep"] + initialDelaySeconds: 120 + periodSeconds: 3 ``` From 2a7ba969aa202ea84c65711e9375a7a5b45c7427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 29 Apr 2024 14:02:51 +0200 Subject: [PATCH 21/22] Using Xdebug with PHPStorm and various updates (#1923) * Using Xdebug with PHPStorm and various updates * Update debugging.md * Delete .idea/workspace.xml * ZTS support * linter --- core/performance.md | 27 ++++++++++-------- distribution/debugging.md | 58 ++++++++++++++++++++++++--------------- 2 files changed, 51 insertions(+), 34 deletions(-) diff --git a/core/performance.md b/core/performance.md index 94d0eb3f719..d1745cf409c 100644 --- a/core/performance.md +++ b/core/performance.md @@ -2,12 +2,12 @@ ## Enabling the Built-in HTTP Cache Invalidation System -Exposing a hypermedia API has [many advantages](http://blog.theamazingrando.com/in-band-vs-out-of-band.html). One of them +Exposing a hypermedia API has [many advantages](http://blog.theamazingrando.com/in-band-vs-out-of-band.html). One is the ability to know exactly which resources are included in HTTP responses created by the API. We used this specificity to make API Platform apps blazing fast. When the cache mechanism [is enabled](configuration.md), API Platform collects identifiers of every resource included in -a given HTTP response (including lists, embedded documents and subresources) and returns them in a special HTTP header +a given HTTP response (including lists, embedded documents, and subresources) and returns them in a special HTTP header called [Cache-Tags](https://support.cloudflare.com/hc/en-us/articles/206596608-How-to-Purge-Cache-Using-Cache-Tags-Enterprise-only-). A caching [reverse proxy](https://en.wikipedia.org/wiki/Reverse_proxy) supporting cache tags (e.g. Varnish, Cloudflare, @@ -16,7 +16,7 @@ This means that after the first request, all subsequent requests will not hit th from the cache. When a resource is modified, API Platform takes care of purging all responses containing it in the proxy’s -cache. This ensures that the content served will always be fresh, because the cache is purged in real time. Support for +cache. This ensures that the content served will always be fresh because the cache is purged in real-time. Support for most specific cases such as the invalidation of collections when a document is added or removed or for relationships and inverse relations is built-in. @@ -24,9 +24,9 @@ inverse relations is built-in. #### Built-in Caddy HTTP cache -The API Platform distribution relies on the [Caddy web server](https://caddyserver.com) which provide an official HTTP cache module called [cache-handler](https://github.com/caddyserver/cache-handler), that is based on [Souin](https://github.com/darkweak/souin). +The API Platform distribution relies on the [Caddy web server](https://caddyserver.com) which provides an official HTTP cache module called [cache-handler](https://github.com/caddyserver/cache-handler), that is based on [Souin](https://github.com/darkweak/souin). -The integration using the cache-handler is quite simple. You juste have to update the `api/Dockerfile` to build your caddy instance with the HTTP cache +The integration using the cache handler is quite simple. You just have to update the `api/Dockerfile` to build your caddy instance with the HTTP cache ```diff # Versions @@ -61,7 +61,7 @@ Update your Caddyfile with the following configuration: } } ``` -This will tell to caddy to use the HTTP cache and activate the tag based invalidation API. You can refer to the [cache-handler documentation](https://github.com/caddyserver/cache-handler) or the [souin website documentation](https://docs.souin.io) to learn how to configure the HTTP cache server. +This will tell to caddy to use the HTTP cache and activate the tag-based invalidation API. You can refer to the [cache-handler documentation](https://github.com/caddyserver/cache-handler) or the [souin website documentation](https://docs.souin.io) to learn how to configure the HTTP cache server. Setup the HTTP cache invalidation in your API Platform project ```yaml @@ -96,6 +96,7 @@ api_platform: ``` ## Configuration + Support for reverse proxies other than Varnish or Caddy with the HTTP cache module can be added by implementing the `ApiPlatform\HttpCache\PurgerInterface`. Three purgers are available, the built-in caddy http cache purger (`api_platform.http_cache.purger.souin`), the http tags (`api_platform.http_cache.purger.varnish.ban`), the surrogate key implementation (`api_platform.http_cache.purger.varnish.xkey`). You can specify the implementation using the `purger` configuration node, @@ -411,7 +412,7 @@ More details are available on the [pagination documentation](pagination.md#parti Blackfire.io allows you to monitor the performance of your applications. For more information, visit the [Blackfire.io website](https://blackfire.io/). -To configure Blackfire.io follow these simple steps: +To configure Blackfire.io follow these steps: 1. Add the following to your `compose.override.yaml` file: @@ -444,12 +445,14 @@ export BLACKFIRE_SERVER_TOKEN=xxxxxxxxxx 3. Install and configure the Blackfire probe in the app container, by adding the following to your `./Dockerfile`: ```dockerfile - RUN version=$(php -r "echo PHP_MAJOR_VERSION.PHP_MINOR_VERSION;") \ - && curl -A "Docker" -o /tmp/blackfire-probe.tar.gz -D - -L -s https://blackfire.io/api/v1/releases/probe/php/alpine/amd64/$version \ + RUN version=$(php -r "echo PHP_MAJOR_VERSION.PHP_MINOR_VERSION.(PHP_ZTS ? '-zts' : '');") \ + && architecture=$(uname -m) \ + && curl -A "Docker" -o /tmp/blackfire-probe.tar.gz -D - -L -s https://blackfire.io/api/v1/releases/probe/php/linux/$architecture/$version \ && mkdir -p /tmp/blackfire \ - && tar zxpf /tmp/blackfire-probe.tar.gz -C /tmp/blackfire \ - && mv /tmp/blackfire/blackfire-*.so $(php -r "echo ini_get('extension_dir');")/blackfire.so \ - && printf "extension=blackfire.so\nblackfire.agent_socket=tcp://blackfire:8307\n" > $PHP_INI_DIR/conf.d/blackfire.ini + && tar zxpf /tmp/blackfire-probe.tar.gz -C /tmp/blackfire \ + && mv /tmp/blackfire/blackfire-*.so $(php -r "echo ini_get ('extension_dir');")/blackfire.so \ + && printf "extension=blackfire.so\nblackfire.agent_socket=tcp://blackfire:8307\n" > $PHP_INI_DIR/conf.d/blackfire.ini \ + && rm -rf /tmp/blackfire /tmp/blackfire-probe.tar.gz ``` 4. Rebuild and restart all your containers diff --git a/distribution/debugging.md b/distribution/debugging.md index 728137aa573..0575a303ed2 100644 --- a/distribution/debugging.md +++ b/distribution/debugging.md @@ -4,31 +4,43 @@ ## Xdebug -The default Docker stack is shipped without a Xdebug stage. It's easy -though to add [Xdebug](https://xdebug.org/) to your project, for development -purposes such as debugging tests or remote API requests. +For development purposes such as debugging tests or remote API requests, +[Xdebug](https://xdebug.org/) is shipped by default with the API Platform distribution. -## Add a Development Stage to the Dockerfile +To enable it, run: -To avoid deploying API Platform to production with an active Xdebug extension, -it's recommended to add a custom stage to the end of the `api/Dockerfile`. +```console +XDEBUG_MODE=debug docker compose up --wait +``` -```Dockerfile -# api/Dockerfile -FROM api_platform_php as api_platform_php_dev +## Using Xdebug with PhpStorm -ARG XDEBUG_VERSION=3.1.3 -RUN set -eux; \ - apk add --no-cache --virtual .build-deps $PHPIZE_DEPS; \ - pecl install xdebug-$XDEBUG_VERSION; \ - docker-php-ext-enable xdebug; \ - apk del .build-deps -``` +First, [create a PHP debug remote server configuration](https://www.jetbrains.com/help/phpstorm/creating-a-php-debug-server-configuration.html): + +1. In the `Settings/Preferences` dialog, go to `PHP | Servers` +2. Create a new server: + * Name: `api` (or whatever you want to use for the variable `PHP_IDE_CONFIG`) + * Host: `localhost` (or the one defined using the `SERVER_NAME` environment variable) + * Port: `443` + * Debugger: `Xdebug` + * Check `Use path mappings` + * Map the local `api/` directory to the `/app` absolute path on the server + +You can now use the debugger! + +1. In PhpStorm, open the `Run` menu and click on `Start Listening for PHP Debug Connections` +2. Add the `XDEBUG_SESSION=PHPSTORM` query parameter to the URL of the page you want to debug or use [other available triggers](https://xdebug.org/docs/step_debug#activate_debugger). + Alternatively, you can use [the Xdebug extension](https://xdebug.org/docs/step_debug#browser-extensions) for your preferred web browser. + +3. On the command-line, we might need to tell PhpStorm which [path mapping configuration](https://www.jetbrains.com/help/phpstorm/zero-configuration-debugging-cli.html#configure-path-mappings) should be used, set the value of the PHP_IDE_CONFIG environment variable to `serverName=api`, where `api` is the name of the debug server configured higher. + + Example: -## Configure Xdebug with Docker Compose Override + ```console + XDEBUG_SESSION=1 PHP_IDE_CONFIG="serverName=api" php bin/console ... + ``` -XDebug is shipped by default with the API Platform distribution. -To enable it, run: `XDEBUG_MODE=debug docker compose up --wait` +## Using Xdebug With VSCode If you are using VSCode, use the following `launch.json` to debug. Note that this configuration includes the path mappings for the Docker image. @@ -51,8 +63,10 @@ Note that this configuration includes the path mappings for the Docker image. } ``` -Note: On Linux, the `client_host` setting of `host.docker.internal` may not work. -In this case you will need the actual local IP address of your computer. +> [!NOTE] +> +> On Linux, the `client_host` setting of `host.docker.internal` may not work. +> In this case you will need the actual local IP address of your computer. ## Troubleshooting @@ -64,6 +78,6 @@ $ docker compose exec php \ php --version PHP … - with Xdebug v3.1.3, Copyright (c) 2002-2021, by Derick Rethans + with Xdebug v…, Copyright (c) 2002-2021, by Derick Rethans … ``` From 17860807ea4729f638cd0718798afc97189bbad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20H=C3=A9bert?= Date: Tue, 24 Sep 2024 14:15:35 +0200 Subject: [PATCH 22/22] fix (images): Use relative links for the symfonycast player --- core/content-negotiation.md | 2 +- core/extending-jsonld-context.md | 4 ++-- core/extending.md | 2 +- core/filters.md | 2 +- core/getting-started.md | 2 +- core/index.md | 2 +- core/jwt.md | 2 +- core/openapi.md | 2 +- core/operations.md | 2 +- core/pagination.md | 2 +- core/security.md | 2 +- core/serialization.md | 8 ++++---- core/testing.md | 2 +- core/validation.md | 2 +- deployment/index.md | 2 +- distribution/debugging.md | 2 +- distribution/index.md | 2 +- distribution/testing.md | 2 +- extra/contribution-guides.md | 2 +- 19 files changed, 23 insertions(+), 23 deletions(-) diff --git a/core/content-negotiation.md b/core/content-negotiation.md index 562822f49e0..cc9a24d3ca0 100644 --- a/core/content-negotiation.md +++ b/core/content-negotiation.md @@ -9,7 +9,7 @@ Using the raw JSON or raw XML formats is discouraged, prefer using JSON-LD inste API Platform also supports [JSON Merge Patch (RFC 7396)](https://tools.ietf.org/html/rfc7396) the JSON:API [`PATCH`](https://tools.ietf.org/html/rfc5789) formats, as well as [Problem Details (RFC 7807)](https://tools.ietf.org/html/rfc7807), Hydra and JSON:API error formats. -

Formats screencast
Watch the Formats screencast

+

Formats screencast
Watch the Formats screencast

API Platform will automatically detect the best resolving format depending on: diff --git a/core/extending-jsonld-context.md b/core/extending-jsonld-context.md index 1ef4eb6b10d..2724aa471d9 100644 --- a/core/extending-jsonld-context.md +++ b/core/extending-jsonld-context.md @@ -2,7 +2,7 @@ ## JSON-LD -

JSON-LD screencast
Watch the JSON-LD screencast

+

JSON-LD screencast
Watch the JSON-LD screencast

API Platform provides the possibility to extend the JSON-LD context of properties. This allows you to describe JSON-LD-typed values, inverse properties using the `@reverse` keyword and you can even overwrite the `@id` property this way. Everything you define @@ -63,7 +63,7 @@ Note that you do not have to provide the `@id` attribute. If you do not provide ## Hydra -

Hydra screencast
Watch the Hydra screencast

+

Hydra screencast
Watch the Hydra screencast

It's also possible to replace the Hydra context used by the documentation generator: diff --git a/core/extending.md b/core/extending.md index 345b6652bc0..c38b26e3c12 100644 --- a/core/extending.md +++ b/core/extending.md @@ -35,4 +35,4 @@ For instance, if you want to send a mail after a resource has been persisted, bu To replace existing API Platform services with your decorators, [check out how to decorate services](https://symfony.com/doc/current/service_container/service_decoration.html). -

Service Decoration screencast
Watch the Service Decoration screencast

+

Service Decoration screencast
Watch the Service Decoration screencast

diff --git a/core/filters.md b/core/filters.md index bae94ba3097..9dea268012b 100644 --- a/core/filters.md +++ b/core/filters.md @@ -12,7 +12,7 @@ By default, all filters are disabled. They must be enabled explicitly. When a filter is enabled, it automatically appears in the [OpenAPI](openapi.md) and [GraphQL](graphql.md) documentations. It is also automatically documented as a `hydra:search` property for JSON-LD responses. -

Filtering and Searching screencast
Watch the Filtering & Searching screencast

+

Filtering and Searching screencast
Watch the Filtering & Searching screencast

## Doctrine ORM and MongoDB ODM Filters diff --git a/core/getting-started.md b/core/getting-started.md index e0c284c8853..ec462033433 100644 --- a/core/getting-started.md +++ b/core/getting-started.md @@ -30,7 +30,7 @@ and what [JSON-LD](https://json-ld.org/) and [Hydra](https://www.hydra-cg.com/) ## Mapping the Entities -

Create an API Resource screencast
Watch the Create an API Resource screencast

+

Create an API Resource screencast
Watch the Create an API Resource screencast

API Platform is able to automatically expose entities mapped as "API resources" through a REST API supporting CRUD operations. diff --git a/core/index.md b/core/index.md index e8c04e79196..56e1d3c3b7f 100644 --- a/core/index.md +++ b/core/index.md @@ -43,6 +43,6 @@ This bundle is extensively tested (unit and functional). The [`Fixtures/` direct ## Screencasts -

SymfonyCasts, API Platform screencasts

+

SymfonyCasts, API Platform screencasts

The easiest and funniest way to learn how to use API Platform is to watch [the more than 60 screencasts available on SymfonyCasts](https://symfonycasts.com/tracks/rest?cid=apip#api-platform)! diff --git a/core/jwt.md b/core/jwt.md index a8f49813ad6..b79eeae919e 100644 --- a/core/jwt.md +++ b/core/jwt.md @@ -7,7 +7,7 @@ The tokens are signed by the server's key, so the server is able to verify that API Platform allows to easily add a JWT-based authentication to your API using [LexikJWTAuthenticationBundle](https://github.com/lexik/LexikJWTAuthenticationBundle). -

JWT screencast
Watch the LexikJWTAuthenticationBundle screencast

+

JWT screencast
Watch the LexikJWTAuthenticationBundle screencast

## Installing LexikJWTAuthenticationBundle diff --git a/core/openapi.md b/core/openapi.md index 6e575edb623..c8f3c5bcb70 100644 --- a/core/openapi.md +++ b/core/openapi.md @@ -4,7 +4,7 @@ API Platform natively supports the [OpenAPI](https://www.openapis.org/) API spec ![Screenshot](../distribution/images/swagger-ui-1.png) -

OpenAPI screencast
Watch the OpenAPI screencast

+

OpenAPI screencast
Watch the OpenAPI screencast

The specification of the API is available at the `/docs.jsonopenapi` path. By default, OpenAPI v3 is used. diff --git a/core/operations.md b/core/operations.md index 072891df0fd..0b6083dcc5f 100644 --- a/core/operations.md +++ b/core/operations.md @@ -3,7 +3,7 @@ API Platform relies on the concept of operations. Operations can be applied to a resource exposed by the API. From an implementation point of view, an operation is a link between a resource, a route and its related controller. -

Operations screencast
Watch the Operations screencast

+

Operations screencast
Watch the Operations screencast

API Platform automatically registers typical [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) operations and describes them in the exposed documentation (Hydra and Swagger). It also creates and registers routes corresponding diff --git a/core/pagination.md b/core/pagination.md index 027cc3b7b99..5120a2f34f3 100644 --- a/core/pagination.md +++ b/core/pagination.md @@ -1,6 +1,6 @@ # Pagination -

Pagination screencast
Watch the Pagination screencast

+

Pagination screencast
Watch the Pagination screencast

API Platform has native support for paged collections. Pagination is enabled by default for all collections. Each collection contains 30 items per page. diff --git a/core/security.md b/core/security.md index 5e319221df1..3bc4e892ed0 100644 --- a/core/security.md +++ b/core/security.md @@ -4,7 +4,7 @@ The API Platform security layer is built on top of the [Symfony Security compone All its features, including [global access control directives](https://symfony.com/doc/current/security.html#securing-url-patterns-access-control) are supported. API Platform also provides convenient [access control expressions](https://symfony.com/doc/current/expressions.html#security-complex-access-controls-with-expressions) which you can apply at resource and operation level. -

Security screencast
Watch the Security screencast

+

Security screencast
Watch the Security screencast

diff --git a/core/serialization.md b/core/serialization.md index 20da77f4f2d..5e368a6448f 100644 --- a/core/serialization.md +++ b/core/serialization.md @@ -4,7 +4,7 @@ API Platform embraces and extends the Symfony Serializer Component to transform PHP entities in (hypermedia) API responses. -

Serializer screencast
Watch the Serializer screencast

+

Serializer screencast
Watch the Serializer screencast

The main serialization process has two stages: @@ -32,7 +32,7 @@ JSON-LD, or JavaScript Object Notation for Linked Data, is a method of encoding ## The Serialization Context, Groups and Relations -

Serialization Groups screencast
Watch the Serialization Groups screencast

+

Serialization Groups screencast
Watch the Serialization Groups screencast

API Platform allows you to specify the `$context` variable used by the Symfony Serializer. This variable is an associative array that has a handy `groups` key allowing you to choose which attributes of the resource are exposed during the normalization (read) and denormalization (write) processes. It relies on the [serialization (and deserialization) groups](https://symfony.com/doc/current/components/serializer.html#attributes-groups) @@ -300,7 +300,7 @@ Refer to the [operations](operations.md) documentation to learn more. ## Embedding Relations -

Relations screencast
Watch the Relations screencast

+

Relations screencast
Watch the Relations screencast

By default, the serializer provided with API Platform represents relations between objects using [dereferenceable IRIs](https://en.wikipedia.org/wiki/Internationalized_Resource_Identifier). They allow you to retrieve details for related objects by issuing extra HTTP requests. However, for performance reasons, it is sometimes preferable to avoid forcing the client to issue extra HTTP requests. @@ -768,7 +768,7 @@ App\Entity\Greeting: ## Changing the Serialization Context Dynamically -

Context Builder & Service Decoration screencast
Watch the Context Builder & Service Decoration screencast

+

Context Builder & Service Decoration screencast
Watch the Context Builder & Service Decoration screencast

Let's imagine a resource where most fields can be managed by any user, but some can be managed only by admin users: diff --git a/core/testing.md b/core/testing.md index e42081f785b..30261b7cbb9 100644 --- a/core/testing.md +++ b/core/testing.md @@ -3,7 +3,7 @@ API Platform provides a set of useful utilities dedicated to API testing. For an overview of how to test an API Platform app, be sure to read [the testing cookbook first](../distribution/testing.md). -

Test and Assertions screencast
Watch the API Tests & Assertions screencast

+

Test and Assertions screencast
Watch the API Tests & Assertions screencast

## The Test HttpClient diff --git a/core/validation.md b/core/validation.md index 407ae9fd64d..16264bddefc 100644 --- a/core/validation.md +++ b/core/validation.md @@ -4,7 +4,7 @@ API Platform takes care of validating the data sent to the API by the client (us By default, the framework relies on [the powerful Symfony Validator Component](https://symfony.com/doc/current/validation.html) for this task, but you can replace it with your preferred validation library such as [the PHP filter extension](https://www.php.net/manual/en/intro.filter.php) if you want to. -

Validation screencast
Watch the Validation screencast

+

Validation screencast
Watch the Validation screencast

## Validating Submitted Data diff --git a/deployment/index.md b/deployment/index.md index b8dc3b07f48..cac63909614 100644 --- a/deployment/index.md +++ b/deployment/index.md @@ -9,7 +9,7 @@ If you want to play with a local Kubernetes cluster, read [how to deploy an API If you don't want to use Docker, keep in mind that the server application of API Platform is a standard Symfony project, while the Progressive Web Application is a standard Next.js project: -

JWT screencast
Watch the Animated Deployment with Ansistrano screencast

+

JWT screencast
Watch the Animated Deployment with Ansistrano screencast

* [Deploying the Symfony application](https://symfony.com/doc/current/deployment.html) * [Deploying the Next.js application](https://nextjs.org/docs/deployment) diff --git a/distribution/debugging.md b/distribution/debugging.md index 0575a303ed2..ea685cd1f6a 100644 --- a/distribution/debugging.md +++ b/distribution/debugging.md @@ -1,6 +1,6 @@ # Debugging -

API Platform debugging screencast
Watch the Debugging API Platform screencast

+

API Platform debugging screencast
Watch the Debugging API Platform screencast

## Xdebug diff --git a/distribution/index.md b/distribution/index.md index c91cac6a5e7..8872da629ce 100644 --- a/distribution/index.md +++ b/distribution/index.md @@ -793,6 +793,6 @@ and [browse it online](https://demo.api-platform.com). ## Screencasts -

SymfonyCasts, API Platform screencasts

+

SymfonyCasts, API Platform screencasts

The easiest and funniest way to learn how to use API Platform is to watch [the more than 60 screencasts available on SymfonyCasts](https://symfonycasts.com/tracks/rest?cid=apip#api-platform)! diff --git a/distribution/testing.md b/distribution/testing.md index 51a00f44421..8870556d967 100644 --- a/distribution/testing.md +++ b/distribution/testing.md @@ -7,7 +7,7 @@ API Platform provides a set of helpful testing utilities to write unit tests, fu Let's learn how to use them! -

Tests and Assertions screencast
Watch the Tests & Assertions screencast

+

Tests and Assertions screencast
Watch the Tests & Assertions screencast

In this article you'll learn how to use: diff --git a/extra/contribution-guides.md b/extra/contribution-guides.md index 17dd84cd79f..ac658d5c8a1 100644 --- a/extra/contribution-guides.md +++ b/extra/contribution-guides.md @@ -7,4 +7,4 @@ **To report a security issue, please refer to [the dedicated document](security.md).** -

JWT screencast
Watch the Contributing back to Symfony screencast (free)

+

JWT screencast
Watch the Contributing back to Symfony screencast (free)