# API Gateway

## Icons

![API Gateway Icon](https://icon.icepanel.io/AWS/svg/App-Integration/API-Gateway.svg)

## About

* To publically expose API's in an environment we use this AWS offering.
* It supports WebSocket Protocol.
* API Gateway handle API versioning.
* Handle multiple environment.
* Handle security i.e., Authentication and Authorization.
* Create API keys, request throttling.
* Swagger/Open API compliant API's could be quickly imported in to API Gateway.
* Tranform and validate requests and response.
* Generate SDK and API specifications.
* Cache API responses.
* Limited timeout of API Gateway request is 29 seconds, but can be customized.

## Endpoint Types

* **Edge Optimized**
  * For global clients, where requests are routed through the CloudFront Edge locations _(improves latency)_.
  * The API Gateway still lives on only one region.
* **Regional**
  * For regions within the same region.
  * Could manually combine the CloudFront _(more control over the caching strategies and distribution)_.
* **Private**
  * Can only be accessed from you VPC using an interface VPC Endpoint _(ENI)_.
  * Use a resource policy to define access.

## API Gateway - Security

* User Authentication through,
  * IAM Roles _(useful for internal applications)_
  * Cognito _(identity for external users)_
  * Custom Authorizer _(your own logic)_
* Custom Domain Name HTTPS security through integrations with AWS Certificate Manager _(ACM)_
  * If using Edge-Optimized endpoint, then certificate must be in **us-east-1**.
  * If using Regional endpoint, then certificate must be in API Gateway region.
  * Must set up CNAME or Alias record in Route 53.

## Stages and deployment

* Changes made to API Gateway, need to be deployed to come into effect.
* Changes are deployed to stages, _(as many as you want)_.
* Stages can be rolled back as history of deployments are kept.

### Stage Variables

* Stage variables are just like environment variables for API Gateway.
* They can be used for changing configuration values.
* Stage variables are passed to context object in AWS Lambda.
* A typical format of stage variable is `${stageVariables.variableName}`
* To use stage variables, appropriate permissions should be present.

#### Stage Variables and Lambda Alias

* Aliases and stages variables can be used to invoke specific version of lambda function deployed through an API Gateway URL.

## Canary Deployment

* Canary deployment could be leveraged for deployment for any stage.
* Based on percentage of traffic chosen the canary channel receives the traffic.
* One can override stage variable for canary.
* Metrics and logs are separated for better monitoring.
* Once canary deployment is done such that weighted distribution of request is happening and new version is successfully deployed, then you can do a Canary promotion.

## Integration Types

| Type                         | Description                                                                                                                                                                                                                                                                                                                                                        |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `MOCK`                       | Returns a response without sending the request to the backend.                                                                                                                                                                                                                                                                                                     |
| `HTTP`                       | Must configure an integration request and response. Setup mapping using mapping templates for request & response.                                                                                                                                                                                                                                                  |
| `HTTP_PROXY`                 | The HTTP proxy integration allows a client to access the backend HTTP endpoints with a streamlined integration setup on single API method. You do not set the integration request or the integration response. API Gateway passes the incoming request from the client to the HTTP endpoint and passes the outgoing response from the HTTP endpoint to the client. |
| `AWS_PROXY` _(Lambda Proxy)_ | Incoming request is passed as is to the destination, the destination is responsible to handle the request and return a response.                                                                                                                                                                                                                                   |
| `AWS`                        | Lets an API expose AWS service actions. In AWS integration, you must configure both the integration request and integration response and set up necessary data mappings from the method request to the integration request, and from the integration response to the method response.                                                                              |

## Mapping Templates

* This is used to modify requests and response.
* Only applicable when integrated with AWS or HTTP service without use of proxy.
* Rename/Modify query string parameters, modify body content, add headers using Velocity Template Language _(VTL)_.
* For mapping template to work use only content type `application/json` or `application/xml`.
* Filter out results _(remove unnecessary data)_.
* Mapping `json` to `xml` and vice-versa.

### Syntax

```json
    {
        "mappedKey": $input.json('$.example')
    }
```

## Open API Specifications

* OpenAPI spec can be import/export into/from API Gateway.
* It can be used to create basics request validations of an API request before proceeding with the integration.
* `x-amazon-apigateway-request-validators` is part of OpenAPI spec that can be used to declare the validations of request body, request parameters etc at API Gateway level.

## Caching

* By default the TTL for a response to live in cache is 300 seconds, max is 3600 seconds.
* Caches are defined at stage level. However, per method level overriding of cache is possible.
* Cache can be encrypted and throttled.
* Cache capacity is between **0.5 GB to 237 GB**.
* It is expensive and not part of Free Tier.

### Cache Invalidation

* Able to invalidate the cache immediately.
* Client can invalidate the cache with header `Cache-Control: max-age=0`, if there is proper authorization.
* If no authorization is imposed then any client can invalidate the API cache.

## API Gateway - Usage Plans & API Keys

* If you want to make an API available as an offering to your customers.
* **Usage Plan:**
  * Who can access one or more deployed API stages and methods.
  * How much and how fast they can access them.
  * Use API Keys to identify API clients and meter access.
  * Configure throttling limits and quota limits that are enforced on individual client.
* **API Keys**
  * Alphanumeric string values to distribute to your customer.
  * This can be combined with usage plan to control access.
  * Throttling limits are applied at the API Keys level.
  * Quotas limits is the overall number of maximum requests.

## CloudWatch Logs

* Logs contains information about request and response body.
* Logs must be enabled at stage level with relevant logs levels such as - `ERROR`, `DEBUG`, `INFO`.
* Can override setting on a per API basis.

### X-Ray

* It can be enabled to get more tracing information about requests in API Gateway.

## CloudWatch Metrics

* Metrics are obtained per stage, but details metrics can be enabled.
* CacheHitCount and CacheMissCount metrics to get efficiency of cache.
* Count metrics gives the total number of API request in a given period of time.
* IntegrationLatency metrics is the time between API Gateway relays a request to the backend and when it receives a response from the backend.
* Latency metrics is the time between API Gateway receives a request from client and when the response is send back to client. Its a sum of integration latency + some other API Gateway overhead latency.
* 4XXError for client side and 5XXError for server side.

## Throttling

* Account Limit
  * By default, it will throttle requests at 10000 rps across all API in an account.
  * Its a soft limits that can be increased on request to AWS support.
  * On reaching the limit, client will receive **429** Too many Requests Error codes. Note, client may retry on this error using appropriate back off strategy.
  * Can set stage limits and method limits to improve performance.

## Gateway Errors

* 4xx Client side Errors

| Code | Description                 |
| ---- | --------------------------- |
| 400  | Bad Request                 |
| 403  | Access Denied, WAF filtered |
| 429  | Quota exceeded, throttle    |

* 5xx Client side Errors

| Code | Description                                                                                                |
| ---- | ---------------------------------------------------------------------------------------------------------- |
| 502  | Bad Gateway. Send due to incompatible output from integration or out of order invocation due to heavy load |
| 503  | Service Unavailable                                                                                        |
| 504  | Integration Failure                                                                                        |

## CORS

* CORS must be enabled when request domain is different than the resource serving domain.
* `OPTIONS` pre-flight request must contain the following headers.
  * `Access-Control-Allow-Methods`
  * `Access-Control-Allow-Headers`
  * `Access-Control-Allow-Origin`

## Security

* IAM permission
  * Create an IAM policy authorization and attach to User/Role.
  * In this case, authentication is done through IAM and authorization is done through an IAM policy.
  * Good to provide access with AWS
  * Leaverages `Sig v4` capability where IAM credentials are in headers.
* Resource policies
  * Similar to lambda resource policies.
  * Main use case is to allow cross-account access, combined with IAM Security.
  * Allow for a specific source IP Address/VPC Endpoint
* Cognito Integration
  * Can fully manage user lifecycle, token expiration automatically.
  * API Gateway can verify identity automatically from AWS Cognito when token is passed. Token is generated by making call to AWS Cognito.
* Lambda Authorizer _(formerly Custom Authorizers)_
  * Token based authorizer, which user bearer token like JWT token or OAuth
  * A request parameter-based Lambda Authorizer _(header, query string, stage variables)_.
  * Lambda must return IAM policy for the user, result policy is cached.
  * Authentication is done by any methods that can be user defined or third party Authentication system and Authorization is done using Lambda function.

## Rest API v/s HTTP API Gateway

| HTTP API                                                                                                   | REST API                                                                            |
| ---------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| Low-Latency, Cost-Effective AWS Lambda Proxy, HTTP Proxy APIs and private Integrations _(no data mapping)_ | Comparatively costly, supports integration with AWS Lambda, IAM, Cognito, IAM roles |
| Supports OIDC and OAuth 2.0 authorization, built in support for CORS                                       | No supports for OAuth 2.x and OpenID Connect,                                       |
| No usage plans and API Keys                                                                                | Have usage plans and API Keys                                                       |

* More about them can be read [here](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-vs-rest.html).

## Web Socket

* [It](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)'s a two-way interactive communication between a user's browser and a server.
* Server can push information to client.
* Useful for stateful applications, real time applications such as chat, collaboration platforms, multiplayer games and financial trading.
* Works with various AWS offerings like Lambda, DynamoDB table, HTTP Endpoints etc.

### Working

*   Client will connect to webSocket URL of the API Gateway of the form,

    ```
        wss://[some-uniqueid].execute-api.[region].amazonaws.com/[stage-name]
    ```
* Once connected _(i.e onConnect)_, the client will establish persistent connection to it.
* If integrated with lambda, it will invoke lambda function with connection-id, which will remain persistent as long as client remains connected with API Gateway.
* This connection-id can be persisted in the DynamoDb along with other meta-data for future reference.

#### Client to Server

* Once connected, client can send messages to server, over the persisted connection through web socket APIs, the messages are called frames.

#### Server to Client

*   Server has the callback connection URL of the form,

    ```
        wss://[some-uniqueid].execute-api.[region].amazonaws.com/[stage-name]/@connections/connectionId
    ```
* This URL can be used to send the data back to clients. Thus establishing a two-way communications.
  * `POST` to send message from the server to client.
  * `GET` to get the latest connection status of connected WS client.
  * `DELETE` delete the connected client from the WS connection.

#### Routing

* Incoming `json` messages are routed to different backend based on route key table available in API Gateway.
  * `$connect`, `$disconnect` and `$default` are the default mandatory routes.
  * Custom routes can be specified in the route key table as well.
* If no route is spent, then send to `$default`.
* You request a route **selection expression** to select the field on `json` to route from, routing expression should be part of request.
  *   Sample route can be specified as follows,

      ```
          $request.body.action
      ```

## Typical API Gateway based Architecture

![API Gateway Architecture](https://574639531-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJDnjsv52I3fJ56WbLgHu%2Fuploads%2Fgit-blob-9baa4539df473413a7b03308a5c4df9384a937b7%2FTypical_API_Gateway_Arch.png?alt=media)
