diff --git a/README.md b/README.md index 7cbc3086df2ac9ce39358e8dcf833e6219d98271..7549820ebd10243a2bd70269c66fce2645a116bf 100644 --- a/README.md +++ b/README.md @@ -2,62 +2,4 @@ [GitLab](https://gitlab.tugraz.at/dbp/relay/dbp-relay-core-bundle) | [Packagist](https://packagist.org/packages/dbp/relay-core-bundle) -## Bundle Config - -Created via `./bin/console config:dump-reference DbpRelayCoreBundle | sed '/^$/d'` - -```yaml -# Default configuration for "DbpRelayCoreBundle" -dbp_relay_core: - # Some string identifying the current build (commit hash) - build_info: ~ # Example: deadbeef - # Some URL identifying the current build (URL to the commit on some git web interface) - build_info_url: ~ # Example: 'https://gitlab.example.com/project/-/commit/deadbeef' - # The title text of the API docs page - docs_title: 'Relay API Gateway' - # The description text of the API docs page (supports markdown) - docs_description: '*part of the [Digital Blueprint](https://gitlab.tugraz.at/dbp) project*' - lock_dsn: '' - messenger_transport_dsn: '%env(MESSENGER_TRANSPORT_DSN)' -``` - -### Locking - -To handle [locking](https://symfony.com/doc/current/components/lock.html) you need to set above `lock_dsn` config, -for example as `lock_dsn: '%env(LOCK_DSN)%'` with an environment variable `LOCK_DSN` in your `.env` file or by any other means. - -For example, you could use [Redis](https://redis.io/) for distributed locking or `semaphore` for local locking. - -Example: - -```dotenv -# Redis (distributed locking) -LOCK_DSN=redis://redis:6379/ - -# Semaphore (local locking) -LOCK_DSN=semaphore -``` - -### Symfony Messenger - -For projects that also use the [Symfony Messenger](https://symfony.com/doc/current/components/messenger.html) -you need to set above `messenger_transport_dsn` config, for example as `messenger_transport_dsn: '%env(MESSENGER_TRANSPORT_DSN)%'` -with an environment variable `MESSENGER_TRANSPORT_DSN` in your `.env` file or by any other means. - -[Redis](https://redis.io/) is also a way for doing this. - -Example: - -```dotenv -MESSENGER_TRANSPORT_DSN=redis://redis:6379/local-messages/symfony/consumer?auto_setup=true&serializer=1&stream_max_entries=0&dbindex=0 -``` - -You need to have a system in place to run the [Symfony Messenger](https://symfony.com/doc/current/components/messenger.html). -Symfony recommends to use [Supervisor](http://supervisord.org/) to do this. You can use -[Supervisor configuration](https://symfony.com/doc/current/messenger.html#supervisor-configuration) to help you with the setup process. - -Keep in mind that you need to **restart** the Symfony Messenger **workers** when you **deploy** Relay API **updates** -to your server, so changes to the messaging system can be picked up. - -If you are using Supervisor to run the Symfony Messenger you can just stop the workers with -`php bin/console messenger:stop-workers`, Supervisor will start them again. +Docs: see <https://gitlab.tugraz.at/dbp/relay/dbp-relay-core-bundle/-/tree/main/docs> diff --git a/docs/config.md b/docs/config.md new file mode 100644 index 0000000000000000000000000000000000000000..9522c0a860331ad734f7a4370c9880e8434c9ca2 --- /dev/null +++ b/docs/config.md @@ -0,0 +1,61 @@ +# Bundle Configuration + +Created via `./bin/console config:dump-reference DbpRelayCoreBundle | sed '/^$/d'` + +```yaml +# Default configuration for "DbpRelayCoreBundle" +dbp_relay_core: + # Some string identifying the current build (commit hash) + build_info: ~ # Example: deadbeef + # Some URL identifying the current build (URL to the commit on some git web interface) + build_info_url: ~ # Example: 'https://gitlab.example.com/project/-/commit/deadbeef' + # The title text of the API docs page + docs_title: 'Relay API Gateway' + # The description text of the API docs page (supports markdown) + docs_description: '*part of the [Digital Blueprint](https://gitlab.tugraz.at/dbp) project*' + # See https://symfony.com/doc/5.3/messenger.html#redis-transport + messenger_transport_dsn: '' # Example: 'redis://localhost:6379/messages' + # https://symfony.com/doc/5.3/components/lock.html + lock_dsn: '' # Example: 'redis://redis:6379' +``` + +## Locking + +To handle [locking](https://symfony.com/doc/current/components/lock.html) you need to set above `lock_dsn` config, +for example as `lock_dsn: '%env(LOCK_DSN)%'` with an environment variable `LOCK_DSN` in your `.env` file or by any other means. + +For example, you could use [Redis](https://redis.io/) for distributed locking or `semaphore` for local locking. + +Example: + +```dotenv +# Redis (distributed locking) +LOCK_DSN=redis://redis:6379/ + +# Semaphore (local locking) +LOCK_DSN=semaphore +``` + +## Symfony Messenger + +For projects that also use the [Symfony Messenger](https://symfony.com/doc/current/components/messenger.html) +you need to set above `messenger_transport_dsn` config, for example as `messenger_transport_dsn: '%env(MESSENGER_TRANSPORT_DSN)%'` +with an environment variable `MESSENGER_TRANSPORT_DSN` in your `.env` file or by any other means. + +[Redis](https://redis.io/) is also a way for doing this. + +Example: + +```dotenv +MESSENGER_TRANSPORT_DSN=redis://redis:6379/local-messages/symfony/consumer?auto_setup=true&serializer=1&stream_max_entries=0&dbindex=0 +``` + +You need to have a system in place to run the [Symfony Messenger](https://symfony.com/doc/current/components/messenger.html). +Symfony recommends to use [Supervisor](http://supervisord.org/) to do this. You can use +[Supervisor configuration](https://symfony.com/doc/current/messenger.html#supervisor-configuration) to help you with the setup process. + +Keep in mind that you need to **restart** the Symfony Messenger **workers** when you **deploy** Relay API **updates** +to your server, so changes to the messaging system can be picked up. + +If you are using Supervisor to run the Symfony Messenger you can just stop the workers with +`php bin/console messenger:stop-workers`, Supervisor will start them again. diff --git a/docs/cron.md b/docs/cron.md new file mode 100644 index 0000000000000000000000000000000000000000..d3b06e61e1c2e579ef60e1bedc24946f041e01eb --- /dev/null +++ b/docs/cron.md @@ -0,0 +1,42 @@ +# Cron Jobs + +The API gateway provides one shared cron command which you should call every few +minutes: + +```bash +./bin/console dbp:relay:core:cron +``` + +For example in crontab, every 5 minutes: + +```bash +*/5 * * * * /srv/api/bin/console dbp:relay:core:cron +``` + +This cron job will regularly prune caches and dispatch a cron event which can be +handled by different bundles. + +To get access to such an even you have to implement an event listener: + +```yaml + Dbp\Relay\MyBundle\Cron\CleanupJob: + tags: + - { name: kernel.event_listener, event: dbp.relay.cron } +``` + +The listener gets called with a `CronEvent` object. By calling +`CronEvent::isDue()` and passing an ID for logging and a [cron +expression](https://en.wikipedia.org/wiki/Cron) you get told when it is time to +run: + +```php +class CleanupJob +{ + public function onDbpRelayCron(CronEvent $event) + { + if ($event->isDue('mybundle-cleanup', '0 * * * *')) { + // Do cleanup things here.. + } + } +} +``` diff --git a/docs/errors.md b/docs/errors.md new file mode 100644 index 0000000000000000000000000000000000000000..0fcf0b2a13c557232c5069797122734ecdbb4d87 --- /dev/null +++ b/docs/errors.md @@ -0,0 +1,57 @@ +# API Errors and Error Handling + +By default Symfony and API Platform convert `HttpException` and all subclasses +to HTTP errors with a matching status code. See +https://api-platform.com/docs/core/errors for details. + +Since API Platform by default hides any message details for >= 500 and < 600 in +production and doesn't allow injecting any extra information into the resulting +JSON-LD error response we provide a special HttpException subclass which +provides those features. + +The following will pass the error message to the client even in case the status +code is 5xx. Note that you have to be careful to not include any secrets in the +error message since they would be exposed to the client. + +```php +use Dbp\Relay\CoreBundle\Exception\ApiError; + +throw new APIError(500, 'My custom message'); +``` + +which results in: + +```json +{ + "@context": "/contexts/Error", + "@type": "hydra:Error", + "hydra:title": "An error occurred", + "hydra:description": "My custom message" +} +``` + +Further more you can include extra information like an error ID and some extra +information in form of an object: + +```php +use Dbp\Relay\CoreBundle\Exception\ApiError; + +throw new APIError::withDetails(500, 'My custom message', 'my-id', ['foo' => 42]); +``` + +which results in: + +```json +{ + "@context": "/contexts/Error", + "@type": "hydra:Error", + "hydra:title": "An error occurred", + "hydra:description": "My custom message", + "relay:errorId": "my-id", + "relay:errorDetails": { + "foo": 42 + } +``` + +If you are using status codes <= 400 and are fine with just the message, then +using any of the builtin exception types is fine. diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000000000000000000000000000000000000..c22ed565d5d60c775443b0b7885e31fcc6c5d92b --- /dev/null +++ b/docs/index.md @@ -0,0 +1,13 @@ +# About + +The core bundle is the central bundle that needs to be installed in every API +gateway and also is a dependency of every other API bundle. + +* It provides functionality that is commonly needed by API bundles (error handling, + logging, etc) +* It integrates the auth bundle with the Symfony security system +* It provides console commands that API bundles can subscribe to +* It configures all dependencies to our needs (api-platform, symfony, etc.) +* and more ... + +A minimal working relay API gateway consists of the core bundle and an auth bundle.