Swan Lake Beta2 is here.
import ballerina/http;
import ballerina/log;

type Person record {|
    string name;
    int age;
|};

http:Client backendClient = check new("http://localhost:9092");

service /call on new http:Listener(9090) {

    resource function get all() returns json|error {
        // Binding the payload to a string type. The `targetType` is inferred from the LHS variable type.
        string result = check backendClient->get("/backend/string");
        log:printInfo("String payload: " + result);

        // A `record` and `record[]` are also possible types for data binding.
        Person person = check backendClient->get("/backend/person");
        log:printInfo("Person name: " + person.name);
        return person;
    }

    // When the data binding is expected to happen and if the `post` remote function gets a 5XX response from the
    // backend, the response will be returned as an [http:RemoteServerError](https://docs.central.ballerina.io/ballerina/http/latest/errors#RemoteServerError)
    // including the error payload, headers, and status code.
    resource function get '5xx() returns json {
        json|error res = backendClient->post("/backend/5XX", "want 500");
        if (res is http:RemoteServerError) {
            http:Detail detail = res.detail();
            return { code:detail.statusCode, payload:<string>detail.body};
        } else {
            return { code: "invalid" };
        }
    }

    // When the data binding is expected to happen and if the client remote function gets a 4XX response from the
    // backend, the response will be returned as an [http:ClientRequestError](https://docs.central.ballerina.io/ballerina/http/latest/errors#ClientRequestError)
    // including the error payload, headers, and status code.
    resource function get '4xx() returns json {
        json|error res = backendClient->post("/backend/err", "want 400");
        if (res is http:ClientRequestError) {
            http:Detail detail = res.detail();
            return { code:detail.statusCode, payload:<string>detail.body};
        } else {
            return { code: "invalid" };
        }
    }
}

service /backend on new http:Listener(9092) {

    resource function get 'string() returns string {
        return "Hello ballerina!!!!";
    }

    resource function get person() returns record {|*http:Ok; Person body;|} {
        return {body: {name: "Smith", age: 15}};
    }

    resource function post '5XX() returns http:NotImplemented {
        return {body:"data-binding-failed-with-501"};
    }
}

Client Data Binding

Through client data binding, the response payload can be accessed directly. The payload type is inferred from the contextually-expected type or from the targetType argument. A possible payload type out of string|xml|json| map<json>|byte[]|record|record[] and http:Response is expected as return value type. When the user expects client data binding to happen, the HTTP error responses (4XX, 5XX) will be categorized as an error (http:ClientRequestError, http:RemoteServerError) of the client remote operation. For more information on the underlying module, see the HTTP module.

import ballerina/http;
import ballerina/log;
type Person record {|
    string name;
    int age;
|};
http:Client backendClient = check new("http://localhost:9092");
service /call on new http:Listener(9090) {
    resource function get all() returns json|error {
        string result = check backendClient->get("/backend/string");
        log:printInfo("String payload: " + result);

Binding the payload to a string type. The targetType is inferred from the LHS variable type.

        Person person = check backendClient->get("/backend/person");
        log:printInfo("Person name: " + person.name);
        return person;
    }

A record and record[] are also possible types for data binding.

    resource function get '5xx() returns json {
        json|error res = backendClient->post("/backend/5XX", "want 500");
        if (res is http:RemoteServerError) {
            http:Detail detail = res.detail();
            return { code:detail.statusCode, payload:<string>detail.body};
        } else {
            return { code: "invalid" };
        }
    }

When the data binding is expected to happen and if the post remote function gets a 5XX response from the backend, the response will be returned as an http:RemoteServerError including the error payload, headers, and status code.

    resource function get '4xx() returns json {
        json|error res = backendClient->post("/backend/err", "want 400");
        if (res is http:ClientRequestError) {
            http:Detail detail = res.detail();
            return { code:detail.statusCode, payload:<string>detail.body};
        } else {
            return { code: "invalid" };
        }
    }
}

When the data binding is expected to happen and if the client remote function gets a 4XX response from the backend, the response will be returned as an http:ClientRequestError including the error payload, headers, and status code.

service /backend on new http:Listener(9092) {
    resource function get 'string() returns string {
        return "Hello ballerina!!!!";
    }
    resource function get person() returns record {|*http:Ok; Person body;|} {
        return {body: {name: "Smith", age: 15}};
    }
    resource function post '5XX() returns http:NotImplemented {
        return {body:"data-binding-failed-with-501"};
    }
}
bal run http_client_data_binding.bal
[ballerina/http] started HTTP/WS listener 0.0.0.0:9090
[ballerina/http] started HTTP/WS listener 0.0.0.0:9092
time = 2021-01-21 19:29:10,007 level = INFO  module = "" message = "String payload: Hello ballerina!!!!"
time = 2021-01-21 19:29:10,092 level = INFO  module = "" message = "Person name: Smith"
# To invoke the `/call/all` resource, use the cURL command below.
curl "http://localhost:9090/call/all"
{"name":"Smith", "age":15}
# To invoke the `/call/5xx` resource, use the cURL command below.
curl "http://localhost:9090/call/5xx"
{"code":501, "payload":"data-binding-failed-with-501"}
# To invoke the `/call/4xx` resource, use the cURL command below.
curl "http://localhost:9090/call/4xx"
{"code":404, "payload":"no matching resource found for path : /backend/err , method : POST"}
import ballerina/http;
import ballerina/log;

type Person record {|
    string name;
    int age;
|};

http:Client backendClient = check new("http://localhost:9092");

service /call on new http:Listener(9090) {

    resource function get all() returns json|error {
        // Binding the payload to a string type. The `targetType` is inferred from the LHS variable type.
        string result = check backendClient->get("/backend/string");
        log:printInfo("String payload: " + result);

        // A `record` and `record[]` are also possible types for data binding.
        Person person = check backendClient->get("/backend/person");
        log:printInfo("Person name: " + person.name);
        return person;
    }

    // When the data binding is expected to happen and if the `post` remote function gets a 5XX response from the
    // backend, the response will be returned as an [http:RemoteServerError](https://docs.central.ballerina.io/ballerina/http/latest/errors#RemoteServerError)
    // including the error payload, headers, and status code.
    resource function get '5xx() returns json {
        json|error res = backendClient->post("/backend/5XX", "want 500");
        if (res is http:RemoteServerError) {
            http:Detail detail = res.detail();
            return { code:detail.statusCode, payload:<string>detail.body};
        } else {
            return { code: "invalid" };
        }
    }

    // When the data binding is expected to happen and if the client remote function gets a 4XX response from the
    // backend, the response will be returned as an [http:ClientRequestError](https://docs.central.ballerina.io/ballerina/http/latest/errors#ClientRequestError)
    // including the error payload, headers, and status code.
    resource function get '4xx() returns json {
        json|error res = backendClient->post("/backend/err", "want 400");
        if (res is http:ClientRequestError) {
            http:Detail detail = res.detail();
            return { code:detail.statusCode, payload:<string>detail.body};
        } else {
            return { code: "invalid" };
        }
    }
}

service /backend on new http:Listener(9092) {

    resource function get 'string() returns string {
        return "Hello ballerina!!!!";
    }

    resource function get person() returns record {|*http:Ok; Person body;|} {
        return {body: {name: "Smith", age: 15}};
    }

    resource function post '5XX() returns http:NotImplemented {
        return {body:"data-binding-failed-with-501"};
    }
}

Client Data Binding

Through client data binding, the response payload can be accessed directly. The payload type is inferred from the contextually-expected type or from the targetType argument. A possible payload type out of string|xml|json| map<json>|byte[]|record|record[] and http:Response is expected as return value type. When the user expects client data binding to happen, the HTTP error responses (4XX, 5XX) will be categorized as an error (http:ClientRequestError, http:RemoteServerError) of the client remote operation. For more information on the underlying module, see the HTTP module.

import ballerina/http;
import ballerina/log;
type Person record {|
    string name;
    int age;
|};
http:Client backendClient = check new("http://localhost:9092");
service /call on new http:Listener(9090) {
    resource function get all() returns json|error {
        string result = check backendClient->get("/backend/string");
        log:printInfo("String payload: " + result);

Binding the payload to a string type. The targetType is inferred from the LHS variable type.

        Person person = check backendClient->get("/backend/person");
        log:printInfo("Person name: " + person.name);
        return person;
    }

A record and record[] are also possible types for data binding.

    resource function get '5xx() returns json {
        json|error res = backendClient->post("/backend/5XX", "want 500");
        if (res is http:RemoteServerError) {
            http:Detail detail = res.detail();
            return { code:detail.statusCode, payload:<string>detail.body};
        } else {
            return { code: "invalid" };
        }
    }

When the data binding is expected to happen and if the post remote function gets a 5XX response from the backend, the response will be returned as an http:RemoteServerError including the error payload, headers, and status code.

    resource function get '4xx() returns json {
        json|error res = backendClient->post("/backend/err", "want 400");
        if (res is http:ClientRequestError) {
            http:Detail detail = res.detail();
            return { code:detail.statusCode, payload:<string>detail.body};
        } else {
            return { code: "invalid" };
        }
    }
}

When the data binding is expected to happen and if the client remote function gets a 4XX response from the backend, the response will be returned as an http:ClientRequestError including the error payload, headers, and status code.

service /backend on new http:Listener(9092) {
    resource function get 'string() returns string {
        return "Hello ballerina!!!!";
    }
    resource function get person() returns record {|*http:Ok; Person body;|} {
        return {body: {name: "Smith", age: 15}};
    }
    resource function post '5XX() returns http:NotImplemented {
        return {body:"data-binding-failed-with-501"};
    }
}
bal run http_client_data_binding.bal
[ballerina/http] started HTTP/WS listener 0.0.0.0:9090
[ballerina/http] started HTTP/WS listener 0.0.0.0:9092
time = 2021-01-21 19:29:10,007 level = INFO  module = "" message = "String payload: Hello ballerina!!!!"
time = 2021-01-21 19:29:10,092 level = INFO  module = "" message = "Person name: Smith"
# To invoke the `/call/all` resource, use the cURL command below.
curl "http://localhost:9090/call/all"
{"name":"Smith", "age":15}
# To invoke the `/call/5xx` resource, use the cURL command below.
curl "http://localhost:9090/call/5xx"
{"code":501, "payload":"data-binding-failed-with-501"}
# To invoke the `/call/4xx` resource, use the cURL command below.
curl "http://localhost:9090/call/4xx"
{"code":404, "payload":"no matching resource found for path : /backend/err , method : POST"}

In the creation of Ballerina, we were inspired by so many technologies. Thank you to all that have come before us (and forgive us if we missed one): Java, Go, C, C++, D, Rust, Haskell, Kotlin, Dart, TypeScript, JavaScript, Python, Perl, Flow, Swift, Elm, RelaxNG, NPM, Crates, Maven, Gradle, Kubernetes, Docker, Envoy, Markdown, GitHub and WSO2.

Cookie Policy

This website uses cookies so that we can provide you with the best user experience. Read our Cookie Policy to find out more.

If you wish to disable cookies you can do so from your browser.

I Understand