Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PBC-3017 Added AppKernel documentation. #2239

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions _data/sidebars/acp_user_sidebar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ entries:
url: /docs/acp/user/app-composition-platform-installation.html
- title: Developing an app
url: /docs/acp/user/developing-an-app.html
nested:
- title: AppKernel
url: /docs/acp/user/app-kernel.html
- title: App manifest
url: /docs/acp/user/app-manifest.html
- title: App configuration
Expand Down
124 changes: 124 additions & 0 deletions docs/acp/user/app-kernel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
---
title: Create an app with AppKernel
description: Learn how to use the AppKernel when developing an App with Spryker's Mini Framework
template: howto-guide-template
---

The [AppKernel](https://github.com/spryker/app-kernel) is a module that provides the default functionality required by most of the apps. The functionality includes:

- Configuration of an app: Receiving a request from the App Store Catalog to configure this app for a Tenant.
- Disconnecting an app: The App gets disconnected from a Tenant through the App Store Catalog.

This document provides describes how to use AppKernel together with Spryker's Mini Framework to develop an app.

## AppKernel
Basically, every app needs to be configured for each Tenant individually. To prevent this logic from being implemented with each PBC, AppKernel provides this functionality by default.

This functionality includes the following components:

- The `\Spryker\Glue\App\Plugin\RouteProvider\AppRouteProviderPlugin` route provider plugin which provides the following Glue endpoints:
- `/private/configure` - to receive the configuration request.
- `/private/disconnect` - to disconnect the app from a Tenant (configuration gets deleted).
- The `\Spryker\Glue\App\Controller\AppConfigController::postConfigureAction()` controller that receives the configuration request.
- The `\Spryker\Glue\App\Controller\AppDisconnectController::postDisconnectAction()` controller that receives the disconnection request.

Additionally, you can extend the AppKernel with your own business logic by using plugins in the provided extension points as outlined in the following sections.

## Install the required modules using Composer

```bash
composer require spryker/app-kernel
```


## Configure routes

Add the `AppRouteProviderPlugin` to `\Pyz\Glue\GlueBackendApiApplication\GlueBackendApiApplicationDependencyProvider::getRouteProviderPlugins()`.

## Extending Glue

In many cases, it is required to add your own validation on top of the default validation that is provided by the AppKernel. We offer extension points for both actions Configure and Disconnect. You can use the same plugin in both places when needed.

### Configure

Add a class that implements `\Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\RequestValidatorPluginInterface` and add it to `\Pyz\Glue\AppKernel\AppKernelDependencyProvider::getRequestConfigureValidatorPlugins()` on the project level when needed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we do this to set up the Configure action? Why do we say "on the project level when needed" Is it an optional step?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's an optional step that might not be required by every App.


This plugin will be executed inside the `\Spryker\Glue\AppKernel\Controller\AppConfigController::postConfigureAction()` before any other action is happening.

### Disconnect

Add a class that implements `\Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\RequestValidatorPluginInterface` and add it to `\Pyz\Glue\AppKernel\AppKernelDependencyProvider::getRequestDisconnectValidatorPlugins()` on the project level when needed.

This plugin will be executed inside the `\Spryker\Glue\AppKernel\Controller\AppConfigController::postDisconnectAction()` before any other action is happening.

## Extending Zed

### Configure

In some cases, you need to do additional things with the passed configuration e.g. sending a request to a third-party application, or manipulating the data before it gets saved into the database.

You can add two plugins:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where should they be added?

Copy link
Contributor Author

@stereomon stereomon Oct 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

\Pyz\Zed\AppKernel\AppKernelDependencyProvider::getConfigurationBeforeSavePlugin()
\Pyz\Zed\AppKernel\AppKernelDependencyProvider::getConfigurationAfterSavePlugin()

Already written here https://github.com/spryker/spryker-docs/pull/2239/files#diff-ea6d8614a903c2b155ec7b2e6be0e98fbfe9a4aa7e142669a0e6595057ea8894R69-R70


- `\Spryker\Zed\AppKernelExtension\Dependency\Plugin\ConfigurationBeforeSavePluginInterface` - This one will be executed before the configuration is saved in the database.
- `\Spryker\Zed\AppKernelExtension\Dependency\Plugin\ConfigurationAfterSavePluginInterface` - This one will be executed after the configuration was saved in the database.

These plugins will be executed inside of the `\Spryker\Zed\AppKernel\Business\Writer\ConfigWriter::doSaveAppConfig()` method in a transaction. When you need to do some business logic for your App then you can use those plugins to do so and add them to the corresponding method in the \Pyz\Zed\AppKernel\AppKernelDependencyProvider on the project level when needed.

The following methods can be used to attach your plugins:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you mean by "attach your plugins"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means adding them to the dependency provider.


- `\Pyz\Zed\AppKernel\AppKernelDependencyProvider::getConfigurationBeforeSavePlugin()` - Use this for plugins that must be executed before the data gets saved to the database.
- `\Pyz\Zed\AppKernel\AppKernelDependencyProvider::getConfigurationAfterSavePlugin()` - Use this for plugins that must be executed after the data was saved to the database.

### Disconnect

In some cases, you need to do additional things before the Tenant gets disconnected from an App (configuration will be deleted).

You can add two plugins:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where should they be added?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

\Pyz\Zed\AppKernel\AppKernelDependencyProvider::getConfigurationBeforeDeletePlugin()
\Pyz\Zed\AppKernel\AppKernelDependencyProvider::getConfigurationAfterDeletePlugin()

But this information is already written here https://github.com/spryker/spryker-docs/pull/2239/files#diff-ea6d8614a903c2b155ec7b2e6be0e98fbfe9a4aa7e142669a0e6595057ea8894R85-R86


- `\Spryker\Zed\AppKernelExtension\Dependency\Plugin\ConfigurationBeforeDeletePluginInterface` - This one will be executed before the configuration is deleted from the database.
- `\Spryker\Zed\AppKernelExtension\Dependency\Plugin\ConfigurationAfterDeletePluginInterface` - This one will be executed after the configuration was deleted from the database.

These plugins will be executed inside of the `\Spryker\Zed\AppKernel\Business\Deleter\ConfigDeleter::deleteConfig()` method. To prevent the further execution you have to throw an exception inside of your plugin to stop the deletion process. Please, provide a clear exception message to make it easy for anyone to fix the underlying issue.

The following methods can be used to attach your plugins:

- `\Pyz\Zed\AppKernel\AppKernelDependencyProvider::getConfigurationBeforeDeletePlugin()` - Use this for plugins that must be executed before the data gets deleted from the database.
- `\Pyz\Zed\AppKernel\AppKernelDependencyProvider::getConfigurationAfterDeletePlugin()` - Use this for plugins that must be executed after the data was deleted from the database.

## Saving the configuration

Each App configuration differs from the other. We made it simple to store any configuration in the database by allowing to pass an array of the configuration to the AppConfigTransfer object. Inside of the AppKernel this array is converted into JSON and stored as such in the database.

```
<?php

$myAppConfigTransfer = new MyAppConfigTransfer();

$appConfigTransfer = new AppConfigTransfer();
$appConfigTransfer->setConfig($myAppConfigTransfer->toArray());

$appKernelFacade = new AppKernelFacade();
$appKernelFacade->saveConfig($appConfigTransfer);
```

## Getting the Configuration

Inside of your App you want to leverage your own Transfer object to work with the configuration. Since the configuration is store as JSON in the database we do the mapping magic inside of the AppKernel. You only need to call the AppKernelFacadeInterface::getConfig() with an AppConfigCriteriaTransfer and the Transfer object you want to populate with the stored configuration. The `AppKernelFacadeInterface::getConfig()` returns your passed TransferInterface populated with the config that was stored as JSON.

```
<?php

$myAppConfigTransfer = new MyAppConfigTransfer();
$appConfigCriteriaTransfer = new AppConfigCriteriaTransfer();
$appConfigCriteriaTransfer->setTenantIdentifier('some-tenant-identifier');

$appKernelFacade = new AppKernelFacade();
$myAppConfigTransfer = $appKernelFacade->getConfig($appConfigCriteriaTransfer, $myAppConfigTransfer);

$myAppConfigTransfer->getFoo();
```


## Summary

When you have done all the mentioned steps you can continue with developing the busines logic of your App. The code that integrates your App into ACP is ready to be used.
Loading