# Http Requests

In order to interact with web services, we have provided a flexible way to send Http requests.

This currently suports:

* String, JSON or Form-typed content
* Custom headers
* Helpers for constructing Urls
* Built-in helpers, allowing you to send requests to the M2 Web Platform

## Sending Requests

The basic function for sending Http requests is via the `Send Http Request` function.

<figure><img src="https://1456550285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoWTlPaoHd1McSakqMigu%2Fuploads%2Fgit-blob-da270d4ea90e6a26e185afff6f9e08a037059928%2Fimage.png?alt=media" alt=""><figcaption><p>Send Http Request</p></figcaption></figure>

The parameters are as follows:

| Argument               | Description                                                                                                                                                                                                            |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Url                    | The Url to send the request to. This must be http or https and specified on the [Allow list](https://docs.msquared.io/creation/unreal-development/features-and-tutorials/web-services/configuring-external-url-access) |
| Verb                   | Must be one of: GET, POST, PUT, PATCH, DELETE. See [Verbs ](#verbs)below.                                                                                                                                              |
| Request Authentication | A built-in authentication method. See [Authentication ](#authentication)below.                                                                                                                                         |
| Request Headers        | Custom headers to send with the request. See [Headers ](#headers)below.                                                                                                                                                |
| Request Body           | The content to send with the request. See [Sending Content](#sending-content) below.                                                                                                                                   |
| On Complete            | The delegate to fire when the request has completed. See [Response Handling](#response-handling) below.                                                                                                                |
| Additional Config      | Additional configuration settings. See [Advanced Configuration](#advaned-configuration) below.                                                                                                                         |

The the Send Http Request function has multiple output pins to allow you to determine how to proceed next.

| Pin             | Description                                                                                                                                                                                            |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Request Sent    | The request was sent to the remote service. The On Complete delegate will be fired with the results.                                                                                                   |
| Invalid Url     | The Url was not valid. It must start with either http or https and be a valid url format                                                                                                               |
| Url Blocked     | The Url was not on the Allow list. See[ Allowed External Urls](https://docs.msquared.io/creation/unreal-development/features-and-tutorials/web-services/configuring-external-url-access) for guidance. |
| Invalid Verb    | The verb must be one of: GET, POST, PUT, PATCH, DELETE. See [Verbs ](#verbs)below.                                                                                                                     |
| Invalid Content | There was a problem processing the content for sending. See [Sending Content](#sending-content) below.                                                                                                 |
| Invalid Headers | There was a problem processing the Http Headers to send. See [Headers ](#headers)below.                                                                                                                |
| Failed to Send  | A problem occurred that meant the request could not be sent. Consult the Unreal log for more information.                                                                                              |

### Urls

Urls must be either http or https based urls and be present on the Allow list. See[ Allowed External Urls](https://docs.msquared.io/creation/unreal-development/features-and-tutorials/web-services/configuring-external-url-access) for guidance.

If you are calling the M2 Web Platform, you can obtain the URL to send to via the helper function.

<figure><img src="https://1456550285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoWTlPaoHd1McSakqMigu%2Fuploads%2Fgit-blob-87d322370a1be47dd8d96184f9f82fadd7b52c94%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

Urls can be formatted using the `Format Url` helper.

<figure><img src="https://1456550285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoWTlPaoHd1McSakqMigu%2Fuploads%2Fgit-blob-a164cd6d2dc4781239ae7e87ad566c80564ceb03%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

This will combine the Base Url with the Path, and add on any query parameter pairs (in url encoded format).

### Verbs

This function supports the following verbs:

* GET
* POST
* PUT
* DELETE
* PATCH

Other verb will be rejected, with the output `Invalid Verb` being executed

### Authentication

#### Built-in Authentication

We currently support two primary built-in authentication methods.

* Delegated Token Auth - For providing M2 Platform identity to external services (see [Identity Validation](https://docs.msquared.io/creation/unreal-development/features-and-tutorials/web-services/validating-identity))
* M2 Web Platform Auth - For authenticating with the M2 Web Platform itself

**Delegated Token Authentication** is an async process, as it requires requesting a token from the web platform.

<figure><img src="https://1456550285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoWTlPaoHd1McSakqMigu%2Fuploads%2Fgit-blob-2e352ad3d89f0dde3afad1a943b32ebec96bd8fc%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

When requesting a token, you will be required to specify the Scope. Doing so adds extra claims to the Delegated Auth Token, so is a useful way of proving to an external service that you have access to a specific M2 World.

{% hint style="info" %}
It's recommended you use the World scope whenever you can
{% endhint %}

The type of scopes supported are:

| Scope          | Description                                                                                                                                                                                                             |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| None           | No scoping information is added                                                                                                                                                                                         |
| Organization   | The `organization_id` claim is added to the token containing the current M2 Organization Id                                                                                                                             |
| Project        | The `organization_id` and `project_id` claims are added; containing the M2 Organization and Project Ids                                                                                                                 |
| World          | The `organization_id`, `project_id` and `world_id` claims are added; containing the M2 Organization, Project and World Ids                                                                                              |
| Launch Context | <p>DEPRECATED. Do not use.<br><br>The <code>organization\_id</code>, <code>project\_id</code> and <code>launch\_context\_id</code> claims are added; containing the M2 Organization, Project and Launch Context Ids</p> |

**M2 Web Platform** authentication is used whenever you are making a request to the M2 Web Platform apis.

<figure><img src="https://1456550285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoWTlPaoHd1McSakqMigu%2Fuploads%2Fgit-blob-c2acaf7ce06e4b4f3bd9f59906e089ef497f2ca9%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

The simplest node is the `Get M2 Web Platform Http Request Auth`, which gets the authentication for the first local user. If the code is running on a server, the server's authentication will be used, if on a client then the auth for the first local player will be used.

This is suitable for systems that have no intention of supporting authenticated bot players.

The other methods resolve the authentication from a specific local Morpheus Actor, Morpheus Actor Component or Auth User Context. These methods are preferable if you are using auth from a Morpheus Actor or Morpheus Actor Component (you can use `Self` as the input), or if you explicitly know the Auth User Context.

{% hint style="info" %}
It's recommended you use the specific context-based auth nodes where possible, as this allows the system to support Authenticated bots in the future
{% endhint %}

### Headers

Http Headers are used to provide additional metadata to a http server. This can include authentication information, or additional context about the request.

We support two "flavours" of header. Normal, and Sensitive.

<figure><img src="https://1456550285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoWTlPaoHd1McSakqMigu%2Fuploads%2Fgit-blob-fb59b3b4b7c13240af1f6d4381fef13d7b1cc206%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

Sensitive Headers are used for things like secrets or tokens and are regarded as write-only from blueprint; they cannot be read, inspected or logged.

Other than the flavour of header, the headers are represented by a Map of String / Value pairs that you can specifiy the content of.

Many M2 Web Platform APIs require you yo specify the Organization, Project and/or World context in the form of headers.

| Scope                       | Headers Required                                                                                                |
| --------------------------- | --------------------------------------------------------------------------------------------------------------- |
| None                        | N/A                                                                                                             |
| Organization                | `x-m2-organization-id`                                                                                          |
| Project                     | <p><code>x-m2-organization-id</code><br><code>x-m2-project-id</code></p>                                        |
| World                       | <p><code>x-m2-organization-id</code><br><code>x-m2-project-id</code><br><code>x-m2-world-id</code></p>          |
| Launch Context (DEPRECATED) | <p><code>x-m2-organization-id</code><br><code>x-m2-project-id</code><br><code>x-m2-launch-context-id</code></p> |

You can obtain this information using the helper nodes provided:

<figure><img src="https://1456550285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoWTlPaoHd1McSakqMigu%2Fuploads%2Fgit-blob-2526848bb466191f2a96f12a91439882af710ec2%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

You should consult the[ API Reference](https://docs.msquared.io/apis-and-tooling/api-reference) to determine which headers to send to the apis.

### Sending Content

We support three types of content:

* JSON
* String
* Form

<figure><img src="https://1456550285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoWTlPaoHd1McSakqMigu%2Fuploads%2Fgit-blob-2d69f97dc00a19f58528fa7905af0343af463fdb%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

In order to send content you must create it from one of the functions.

JSON Content can be created from either a `Json Object` or a `Json Value` (see [JSON Handling](https://docs.msquared.io/creation/unreal-development/features-and-tutorials/web-services/working-with-json))

String Content can be created from a String, with an option to specify an explicit content type (by default it uses `Content-Type: text/plain`.

Form Content will encode a Map of String/String pairs using Url Encoding. Content will be sent using the `Content-Type: application/x-www-form-urlencoded`.

### Advaned Configuration

This is an additional configuration structure that allows you to configure retries and how many redirects the request will follow.

<figure><img src="https://1456550285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoWTlPaoHd1McSakqMigu%2Fuploads%2Fgit-blob-7fd070a5acb13ce37f37e2bf175d1ffdfb6a25cf%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

When configuring retries, the request will attempt up to the Max Attempts before failing; it will apply backoffs up to a max backoff interval. We use the "Full Jitter" approach described in by [Amazon](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/). This means we have a high amount of randomization in our retries, but will increase the time between attempts.

## Response Handling

Once a request has been sent, you need to handle the response. \\

<figure><img src="https://1456550285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoWTlPaoHd1McSakqMigu%2Fuploads%2Fgit-blob-c8243c40a8e2bdc015c79329bdf1bd531ed88436%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

The response is handled via a custom event. This event has 4 arguments:

| Argument         | Description                                                                                                                           |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| Response Status  | An enum to help classify the Response Code                                                                                            |
| Response Code    | The Http Status code from the server. This will be 0 in the case that the request failed to send (eg connection issues, or otherwise) |
| Response Headers | The Http Headers that were returned by the server                                                                                     |
| Response Body    | The content that the server sent back                                                                                                 |

### Response Status

This is an enum to help classify the Http Response Codes returned. This list is not exhaustive, but covers the main cases that are experienced.

| Status            | Description                                                                                                                           |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| OK                | The request was susccessful. Wraps status codes 200 to 206 inclusive.                                                                 |
| Not Found         | Returned when the server returns a 404                                                                                                |
| Bad Request       | Returned when the server rejects the request with a 400 error                                                                         |
| Unauthorized      | Returned when the server rejects the request with a 401 error. This usually means you don't have an authentication token or key.      |
| Forbidden         | Returned when the server rejects the request with a 403 error. This usually means your authentication credentials are not sufficient. |
| Connection Failed | Returned when the connection to the server fails.                                                                                     |
| Transient Error   | Wraps a few status codes; typically in the 50x range. These requests are usually safe to retry after a wait.                          |
| Not Sent          | The request failed to send; this usually happens if the request was internally deferred but was unable to be processed.               |
| Other Error       | The request failed but wasn't classified in previous categories. Inspect the Response Code to determine the error.                    |

### Response Code

This is the Http Status Code sent by the server. Consult [MDN ](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status)for an exhaustive description of each.

### Response Headers

This is a structure that contains a Map of String/Value headers returned from the server.

<figure><img src="https://1456550285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoWTlPaoHd1McSakqMigu%2Fuploads%2Fgit-blob-e9342df133199046ba6bbf39d0b1c30340386226%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

### Response Content

This is the content returned by the server. We support both JSON and String-based content.

<figure><img src="https://1456550285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoWTlPaoHd1McSakqMigu%2Fuploads%2Fgit-blob-9e9e6fd6b0dedeb4a66bd0471d75316c52593376%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

The content type can be explicitly determined by using the `Get HttpResponse Content Type` node.

JSON content can be parsed into either a `JSON Object` or a `JSON Value` (see [JSON Handling](https://docs.msquared.io/creation/unreal-development/features-and-tutorials/web-services/working-with-json) for how to process it). Normally, we check for a well known JSON content type (`application/json` or `text/json`) when deserializing the content to JSON. Some services return a non-standard type (eg `text/javascript` or otherwise) which causes the parsing to fail. If you know the service you're using does this, you can enable `Ignore Content Type`.

String content is the string content of the request. If you are expecting the content to match a specific content type (eg: `application/xml`), then you can specify it in the `Typed String Content` function.

Binary content is not supported at this time; meaning downloading images, videos or other non-text based content will result in unprocessable content.
