# Response handling examples

In this topic, we'll examine a couple of HTTP response handling examples. To try examples yourself, explore the auth-requests and test-responses [requests
collections](http-client-in-product-code-editor.html#open-requests-collection).

## Check response headers, body, and content type

In this example, we will create several tests to verify the following:

* The request is executed successfully, that is, the response status is 200.

* Headers are received within the response body.

* The response's content type is application/json.

To create a test, we call the `test` method of the [client](http-client-reference.html) object. Inside the test, we can assert a specific condition by calling the `assert` method of the `client` object and refer to various properties of the [response](http-response-reference.html) object to validate them.

```JAVASCRIPT
// Check response status, headers, and content-type
GET https://httpbin.org/get

> {%
    client.test("Request executed successfully", function() {
        client.assert(response.status === 200, "Response status is not 200");
    });

    client.test("Headers option exists", function() {
        client.assert(response.body.hasOwnProperty("headers"), "Cannot find 'headers' option in response");
    });

    client.test("Response content-type is json", function() {
        var type = response.contentType.mimeType;
        client.assert(type === "application/json", "Expected 'application/json' but received '" + type + "'");
    });
%}
```

## Use global variables

In this example, we will capture a value from the received response into a [global variable](http-client-reference.html#global-variables-storage-reference), which can be then used in subsequent requests.

The first request involves a response handler script, which saves an authentication token from the received response body into the `auth_token` variable under [client.global](http-client-reference.html#global-variables-storage-reference). To achieve this, we use the `client.global.set(VariableName, VariableValue)` construction. As the `VariableValue` argument, we use the value of the `token` field from the [response body](http-response-reference.html#response-properties) returned by the server. This value is then assigned to the `"auth_token"` variable.

```HTTP_REQUEST_FULL
POST https://examples.http-client.intellij.net/body-echo
Content-Type: application/json

{
"token": "my-secret-token"
}

> {% client.global.set("auth_token", response.body.token); %}
```

After the request is executed, the `auth_token` variable can be accessed from subsequent requests (in the `{{auth_token}}` variable) and response handler scripts (by means of the `client.global.get("auth_token")` construction).

```HTTP_REQUEST
//Accessing a variable
GET https://examples.http-client.intellij.net/headers
Authorization: Bearer {{auth_token}}
```

To obtain a value from a response header, use the `valueOf` method of the [headers](http-response-reference.html#headers-reference) object. If several headers with the same name are received, use the `valuesOf` method instead. This will return an array of all response header values.

```GENERIC
POST https://httpbin.org/cookies

//Saving a cookie from the first Set-Cookie header
> {%
    client.global.set("my_cookie", response.headers.valuesOf("Set-Cookie")[0]);
%}
```

## Save a cookie as a global variable

In this example, we will send a request that returns a cookie, extract that cookie from the response using a response handler script, save its value as a [global variable](http-client-reference.html#global-variables-storage-reference), and then reuse it in a subsequent request.

Suppose an endpoint returns a `SOCS` cookie in the response. We use the [response.cookiesByName("SOCS")](http-response-reference.html#cookies-by-name) method to find and extract this cookie from the response.

Saving the cookie value as a global variable (`client.global.set()`) allows us to reuse it in subsequent requests. In the next request, we reference `{{SOCS_COOKIE}}` in the `Cookie` header to send the extracted value.

```JAVASCRIPT
            GET https://www.google.com

> {%
    const cookie = response.cookiesByName("SOCS")[0];

    if (cookie) {
        client.global.set("SOCS_COOKIE", cookie.value);
        console.log("Saved SOCS_COOKIE =", cookie.value);
    } else {
        console.log("SOCS cookie not found");
    }
%}

###

// Request 2 — Send the saved cookie to a test endpoint that echoes cookies
GET https://httpbin.org/cookies
    Cookie: SOCS={{SOCS_COOKIE}}
```

## Process each line of an event stream

If you subscribe to an event stream, a server will automatically send events to your client when new data becomes available. This data can be in the form of Server-Sent Events or newline-delimited JSON (NDJSON). In IntelliJ IDEA, you can use the HTTP Client [response.body.onEachLine](http-response-reference.html#textstreamresponse_reference) method to call a function on each line of this event stream.

Suppose you have a server that regularly sends information on the gold price. In this example, let's write a response handler script, which does the following:

1.  Takes each chunk of data (JSON object) received from the server and logs the price value. When you run the request, you can view the logged info in the Response Handler tab of the Services tool window.

2.  Stops processing the received data when the number of events exceeds 10. Note that this does not unsubscribe you from the event stream – you'll keep receiving events as long as the HTTP connection is open (check the Console tab of the Services tool window).

3.  Tests the obtained chunks of data: if the price is less than 45, the test fails. You can view the test results in the Tests tab of the Services tool window.

```JAVASCRIPT
GET localhost/stocks/subscribe?symbol=GOLD

> {%
var updatesCount = 0;
response.body.onEachLine(
    (symbolUpdate, unsubscribe) => {
        updatesCount++;
        client.log(symbolUpdate.pricePresentation);
        if (updatesCount > 10) {
            unsubscribe();
            return;
        }

        client.test("Price test " + updatesCount, () => {
            client.assert(symbolUpdate.lastPrice >= 45, "Price must be >= 45");
            client.log(symbolUpdate.pricePresentation);
        });
    }
)
%}
```

## Handle XML responses using DOM APIs

If the `Content-Type` of a response is XML (for example, `application/xml` or `text/xml`) the HTTP Client exposes `response.body` as a [DOM Document](https://developer.mozilla.org/en-US/docs/Web/API/XMLDocument). To parse and validate the response, you can use the [supported DOM methods](javascript-api-supported-by-http-client.html#dom-methods) directly. If you want to apply string operations or regex, you can serialize a DOM `Document` to a string using `new XMLSerializer().serializeToString(response.body)`.

> **Note:**
> In error messages, the DOM `Document` may appear as `XmlDomDocument`. This is the internal implementation backing `response.body` for XML responses.

### XML response validation

Suppose a server returns a breakfast menu in XML format. In this example, the response handler script extracts values from the XML document and validates them using tests.

```JAVASCRIPT
GET https://www.w3schools.com/xml/simple.xml

> {%
    client.test("First food item is Belgian Waffles", () => {

        const foods = response.body.getElementsByTagName("food");
        client.assert(foods.length > 0, "No food elements found");

        const firstFood = foods[0];

        const name = firstFood
            .getElementsByTagName("name")[0]
            .textContent
            .trim();

        const calories = firstFood
            .getElementsByTagName("calories")[0]
            .textContent
            .trim();

        client.log("Name:", name);
        client.log("Calories:", calories);

        client.assert(name === "Belgian Waffles", "Unexpected food name: " + name);
        client.assert(calories === "650", "Unexpected calories: " + calories);
    });
%}
```

The script parses the `response.body` in the DOM `Document` format and performs the following actions:

* Retrieves all `food` elements using `getElementsByTagName()`.

* Ensures that at least one `food` element is present.

* Selects the first `food` element. Then, extracts the text values of its nested `name` and `calories` elements using `textContent`.

* Verifies that the extracted values match the expected ones using `client.assert()`.

