# Accessing HTTP with $http Resolver

This guide explains how to use the `$http` value resolver in DTS to invoke REST APIs directly from DTS functions. It includes syntax, examples, and details about the response structure.

---

## 1. Overview of `$http`

The `$http` resolver acts as an HTTP client to pre-configured Outbound API Gateway or Internal routes, allowing you to invoke any HTTP method on those routes. Any response from the upstream service is treated as a success case unless explicitly handled otherwise.  To be clear - `$http` places significant limitations on what routes may be accessed, and the authentication/authorization methods used - these are not available to be configured on a per-call basis like in a typical API client.  The lack of flexibility is intentional as a security precaution to prevent abuse.

As currently implemented, the effective timeout is the minimum of dts function timeout, and OAGW/Internal route timeout. HTTP timeout is not implemented at the moment.  It will be included in future improvement, along with allowed_status_codes.

## Syntax:
```
$http[<route_cti_id>](
  method=<http_method>,
  path=<path_component>,
  body=<body_component>,
  header=<header_component>,
  options=<options_list>
)
```

## Parameters: 
- **route_cti_id** (Required): Specifies the Outbound Gateway's (OAGW) or Internal Route CTI entity, this must be pre-configured.
- **method** (Optional): Defines the HTTP method (e.g., GET, POST, PUT, DELETE). Defaults to `GET`.
- **path** (Optional): Includes the URI and optionally query parameters. Defaults to the root URI of the Route.
- **body** (Optional): Currently, content-type `application/json` is added to headers in all cases, and response content-type is not validated.  Plan to add support for optional content-types and validation in the future.
- **header** (Optional): Provides request header parameters as a JSON array with name/value pairs.
- **options** (Optional): Supports a JSON object compliant with the schema below.

## Supported Options Schema:
| Field               | DataType   | Description                                                                 | Default Behavior |
|---------------------------|------------|-----------------------------------------------------------------------------|------------------|
| **no_redirect**          | boolean    | Automatically follows redirect (3xx). Location returned in response headers.| `true`           |


### Planned Options:
_**Not Currently Supported!**_
| Field               | DataType   | Description                                                                 | Default Behavior |
|---------------------|------------|-----------------------------------------------------------------------------|------------------|
| **allowed_status_codes** | integer[] | Specifies status codes treated as success. `0` allows all status codes.    | `0`              |
| **timeout**         | string     | HTTP request timeout in ISO 8601 duration format.                           | -                |
| **allowed_content_types** | string[]   | Specific response content_type should be treated as a success case. If upstream returns content_type not in this list, then $http will response with error code  ~a.p.dts.resolver.http.v1.0~a.p.unexpected_response.v1.0 | `application/json` |
| **bypass_cache** | boolean | true  value tells DTS runtime not to use cached value for this $http call. In other words, it will always invoke the upstream API. | `false` |

---

## Example: Fetching Posts from Example's Service API

The following example demonstrates how to use the `$http` resolver to fetch a list of posts from the service's API, assuming a pre-configured route for service.

### Example:
```json
$http[cti.a.p.oagw.route.v1.0~example.app.service_route.v1.0](
  method="GET",
  path="/posts",
  headers={
    Accept: "application/json"
  },
  options={
    timeout: "PT10S", // 10-second timeout
    allowed_status_codes: [200]
  }
)
```

### Explanation:
- **route_cti_id**: `"example_service_route_id"` is a placeholder for the Route CTI entity configured to point to `https://service.example.com`.
- **method**: `GET` is used to retrieve data.
- **path**: `/posts` specifies the endpoint for fetching posts.
- **header**: Includes a header to accept JSON responses.
- **options**: Sets a timeout of 10 seconds and allows only HTTP 200 status codes as successful responses.

### Notes:
- Ensure the `example_service_route_id` is correctly configured in the DTS Outbound Gateway to point to `https://service.example.com`.
- Use CEL expressions like `has(body)` to check for the presence of the response body before accessing it.

## 2. Response Structure

The `$http` resolver returns a predefined structure as shown below.
The response structures are different in case of success and error case.

### HttpResolverReturn:

Its declared in [dts/resolver_types/http_resolver.raml](../resolver_types/http_resolver.raml?plain=1#L24)

```yaml
HttpResolverResponse:
  (cti.cti): cti.a.p.dts.resolver.http.response.v1.0
  description: Response type provided by `$http` resolver
  additionalProperties: false
  type: object
  (cti.schema): 
    - cti.a.p.err.v1.0~a.p.dts.resolver.http.v1.0
    - cti.a.p.dts.resolver.http.upstream_response.v1.0

HttpResolverSuccessResponse:
  (cti.cti): cti.a.p.dts.resolver.http.upstream_response.v1.0
  type: object
  properties:
    status_code: integer
    body?: any # Check existence using `has()` CEL expression
    headers?: # Check existence using `has()` CEL expression
      description: The response headers from upstream are represented as properties under this field.
      properties:
        //: string | string[]
    content_length:
      type: integer
      description: >
        Content length in body. `-1` means length unknown.
        Values >= 0 indicate the number of bytes readable from `body`.
    proto: string # HTTP Protocol (e.g., "HTTP/1.1")
```

### Response Fields:
| Component       | Required? | Description                                                                 |
|-----------------|-----------|-----------------------------------------------------------------------------|
| **status_code** | Required  | HTTP status code.                                                           |
| **body**        | Optional  | Response body.                                                              |
| **headers**     | Optional  | Response headers.                                                           |
| **content_length** | Required  | Content length in body. `-1` means unknown; values >= 0 indicate readable bytes. |
| **proto**       | Required  | HTTP Protocol (e.g., "HTTP/1.1").                                           |

---

### Example Response

#### Expected Response:
```yaml
status_code: 200
body:
  - userId: 1
    id: 1
    title: "sunt aut facere repellat provident occaecati excepturi optio reprehenderit"
    body: "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum..."
  - ...
headers:
  Content-Type: "application/json; charset=utf-8"
  Content-Length: "1234"
content_length: 1234
proto: "HTTP/1.1"
```
---

## 3. Error Handling

The `$http` resolver may return errors to indicate problems encountered during the execution of an HTTP request. Proper error handling is essential to ensure the stability and reliability of DTS functions that utilize `$http`.

**Summary of Possible $http Errors**

The `$http` resolver can return the following types of errors:

* **HttpConnectionError:** Indicates errors related to establishing a connection with the upstream server.
* **HttpTimeoutError:** Signifies that the request timed out before receiving a response.
* **HttpUnexpectedResponseError:** Represents errors due to receiving an unexpected response from the upstream server (e.g., unexpected status code or content type).

**General Notes on Error Handling**

* When using the `$http` resolver, always include error handling logic to manage potential failures.
* Examine the error type to determine the specific cause of the error and take appropriate action.
* The `payload` property within the `HttpError` and its derived types often contains valuable information for debugging, such as details about the request or the received response.
* Pay close attention to the `HttpUnexpectedResponseError`, as it provides details about the unexpected response from the server, including the status code, headers, and body.

**Detailed Error Type Information**

The error definitions can be found in [dts/errors/http_errors.raml](../errors/http_errors.raml)

| Error Type | CTI ID | Description | Typical Cause |
|------------|--------|-------------|----------------|
| **HttpConnectionError** | `cti.a.p.err.v1.0~a.p.dts.resolver.http.v1.0~a.p.connection.v1.0` | Raised when the HTTP request fails due to connection issues (e.g., unreachable server, DNS failure). | Server down, incorrect endpoint, network issues |
| **HttpTimeoutError** | `cti.a.p.err.v1.0~a.p.dts.resolver.http.v1.0~a.p.timeout.v1.0` | Raised when the HTTP request times out while waiting for a server response. | Long response time, unresponsive upstream |
| **HttpUnexpectedResponseError** | `cti.a.p.err.v1.0~a.p.dts.resolver.http.v1.0~a.p.unexpected_response.v1.0` | Raised when the HTTP response has an unexpected status code or payload outside expected values. | Status code not in [200–299] range, invalid response body or content-type |