# Version 13

Index: 
* [Using the API Controller](#using-the-api-controller)
* [Configuring for Cloud Deployment]()

Version 13 introduces a few fundamental chenges: 

1. **Simplified JWT Token Verification**. <br>
Custom JWT tokens are now verified without the need of an API call. <br>
They are just verified by using the `jwt.verify()` method, that uses the secret (JWT Signing Key) to check the validity of the token. <br>
If the key stored in your **Secrets Manager** is the key that was used to sign the token than the auth succeeds. 

That also means that:

* `getCustomAuthVerifier()` in the `Config` is no longer needed (it has been removed from the interface). 
* `getProps()` should now return `customAuthProvider: "toto"` as part of the payload, if the service supports Toto Auth.
* `getSigningKey()` is a new method that should return the JWT signing key used to sign Toto tokens (the key must be loaded from the secrets manager).


2. **Multi-hyperscalers**<br>
A Toto Microservice can now run on **GCP and AWS**. That means that concretely: 
    * Secrets are extracted from GCP Secrets Manager or AWS Secrets Manager based on the enviornment the Microservice runs in. <br>
    The environment is made by: 
        * A Hyperscaler (env var)
        * An Enviroenmtn (e.g. dev, test, prod)

3. **Support to base path**<br>
You can now specify a base path (e.g. `/pippo`) to **prepend** to all the endpoints' paths. <br>
*Example: specifying the base path `/pippo` will mean that when you register a path, e.g. `api.path('GET', '/hello', ...)` the path will **not** be available under `<ms-endpoint>/hello` but under `<ms-endpoint>/pippo/hello`. <br>
Note that: 
    * The path `/health` will **not** be under the added base path. 
    * The smoke path `/` will **not** be under the added base path neither.

4. **`/health`** Endpoint
Added a `/health` endpoint that is supposed to be used as a health endpoint (duh..).
 
## Using the API Controller
The API Controller can be used as follows: 

### Import
Import through `import { TotoAPIController } from "toto-api-controller";`

---
### Instantiate
Instantiate through `const api = new TotoAPIController("your api name", new ControllerConfig())`. <br> 

The instantiation requires that you have defined a `ControllerConfig` class that `implements TotoControllerConfig`.<br>
This class will thus have to define the following methods:

 * `async load()` that loads any configuration needed (e.g. secrets)

 * `getProps(): ValidatorProps` that returns the following properties, **all optional**: 
    * `noAuth`: default false, if set to true, the service will bypass the verification of the Authorization header. This means that the API will be **unauthenticated**. 
    * `noCorrelation`: default false, if set to true, the caller won't have to pass a `x-correlation-id` header
    * `minAppVersion`: default null, if set to a value, the caller will have to provide a `x-app-version` header and the API Controller will verify that the provided header value is greater or equal than this `minAppVersion`
    * `customAuthProvider`: in case a custom auth provider is used (e.g. Toto), the name of the authProvider should be used. This name **must** match the content of the `authProvider` field of the JWT Token provided when interacting with the API.
 
 * `getExpectedAudience(): string` that returns the expected **Audience** in the `aud` field of the JWT token

 * `getSigningKey(): string` that returns the JWT Signing Key that is used to check the validity of custom auth tokens.

**IN THIS VERSION** you can now **specify a base path** to be **prepended** to your routes: 
```
const api = new TotoAPIController("toto-ms-ex1", new ControllerConfig(), { basePath: '/ex1' });
```
In the example above, all path registrations using the `api.path()` method will prepend `/ex1` to the path. <br>
*Example: specifying the base path `/pippo` will mean that when you register a path, e.g. `api.path('GET', '/hello', ...)` the path will **not** be available under `<ms-endpoint>/hello` but under `<ms-endpoint>/pippo/hello`. <br>
**Note** that you can **avoid** this behaviour on a per-path basis, see below.

---
### Register API Paths
To register an API path, add a line for each path: <br>
`api.path("GET", "/games", new GetGamesOverview())`

The `new GetGamesOverview()` instantiates a `TotoDelegate`. <br>
Toto Delegates have the responsibility to handle requests to a given path.<br>
They implement the method: <br>
`async do(req: Request, userContext: UserContext, execContext: ExecutionContext): Promise<any>`

If you have configured a base path on the controller but want a specific endpoint (path) to ignore it, you can do the following: 
`api.path('GET', '/pippo', new SmokeDelegate(), { ignoreBasePath: true });`

#### UserContext
The variable `userContext` contains the following fields:
 * `userId`: the id of the user according to the Identity Provider
 * `email`: the user email
 * `authProvider`: a string identifying the IDP

#### ExecutionContext
The variable `executionContext` contains the following: 
 * `logger`: a `TotoLogger` that can be used to log messages to the console out
 * `cid`: the correlation id
 * `appVersion`: the app version (content of the `x-app-version` header, if present)
 * `apiName`: the name of this API
 * `config`: the instance of the `TotoControllerConfig` used by this API

---
### Start
To start the API Controller, just add this: 
```
api.init().then(() => {
    api.listen()
});
```

