# Implementing App Managers

Apps are used to allow access to clients, as well as to be able to securely publish events to your users by using signatures generated by app secret. In this document you will have a small insight about how you can configure your own apps, as well as leveraging the official ecosystem apps to get started easily.

## Default Application

Echo Server comes with a single default app whose data can be changed using `APP_DEFAULT_*` environment variables, as explained in the [Environment Variables docs](ENV.md#default-application).

## Array Driver

The default driver is called `array`. This is a static array in-memory that is kept while the Echo Server process is running. Whenever a connection is made or an event is broadcasted, the app credentials will be checked using this method.

You might use the `APP_DEFAULT_*` variables to set the default app details, or you can specifiy a JSON-serialized list of apps with `APPS_LIST` that will override the `APP_DEFAULT_*` variables.

## HTTP API Driver

You might want to store multiple apps in a dynamic & controlled manner and not locally, at the process level.

The `api` driver comes to help with that. You can specify the host, endpoint and a verification token that can make requests on Echo Server's behalf and retrieve the apps from another server via a HTTP request.

In Laravel, you can use [soketi/echo-server-core](https://github.com/soketi/echo-server-core), and extend the functionality for the `api` driver by storing the apps into database. It comes out-of-the-box with migrations and models, as well as the controller needed, so you can immediately extend the core functionality for Echo Server.

### Implementing your own API Driver

If you decide to implement your own API handler, you should expose an endpoint on your webserver. This route is by default `/echo-server/app`, and can be modified by `APPS_MANAGER_ENDPOINT`.

Read about the full configuration of the App Management in the [Environment Variables documentation](ENV.md#apps-manager).

Take a look on how this is implemented in Echo Server Core. Please note that all parameters come as query strings:

```php
class AppsController extends Controller
{
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;

    /**
     * Initialize the controller.
     *
     * @return void
     */
    public function __construct()
    {
        // Check if the given ?token=... is correct.
        $this->middleware(AuthenticatesWithToken::class);
    }

    /**
     * Get an app by ID.
     *
     * @param  \Soketi\EchoServer\Contracts\AppsManager  $appsManager
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function show(AppsManager $appsManager, Request $request)
    {
        if ($request->appId) { // Check if ?appId=... is present to retrieve app by ID.
            $app = $appsManager->findById($request->appId);
        } elseif ($request->appKey) { // Check if ?appKey=... is present to retrieve app by ID.
            $app = $appsManager->findByKey($request->appKey);
        } else {
            $app = null; // Invalidate the request.
        }

        // Throw 404 if app is not found.
        if (! $app) {
            return response()->json(['app' => null], 404);
        }

        // Send the app with the `app` key.
        return response()->json([
            'app' => $app->toArray(),
        ]);
    }
}
```

An example response looks like this, and the structure must be maintained:

```json
{
    "app": {
        "id": 1,
        "key": "echo-app-key",
        "secret": "echo-app-secret",
        "maxConnections": 100,
        "enableStats": false,
        "enableClientMessages": true,
        "maxBackendEventsPerMinute": -1,
        "maxClientEventsPerMinute": -1,
        "maxReadRequestsPerMinute": -1
    }
}
```

**You should not fear the secrets are being exposed. As long as the authentication is secured by the token, all handling for the app is internal-only! It's usually a good practice to make sure the API is behind a firewall and only locally-accessible for Echo Server.**
