ballerinaballerina-http

How to set a JSON request body and add headers in HTTP post request in Ballerina?


I'm implementing the following method to call an external POST API by sending a JSON body (jsonObj) and also need to add a header. How can I accomplish this?

resource function post createUser(http:Caller caller, http:Request request) returns error? {

   string jsonString = check request.getTextPayload();
   json jsonObj = check value:fromJsonString(jsonString);

   http:Client httpEndpoint = check new ("https://test.com"/);
   http:Response getResponse  = check httpEndpoint->post("/users");
   var jsonPayload = check getResponse.getJsonPayload();
   http:Response response = new;
   response.statusCode = getResponse.statusCode;
   response.setJsonPayload(jsonPayload);
   check caller->respond(response);
}

Solution

  • The second and third parameters of the post remote method are the payload and headers respectively. https://central.ballerina.io/ballerina/http/latest#Client-post

    So you can do something like,

    http:Response getResponse = check httpEndpoint->post("/users", jsonObj, {"header1": "value1", "header2": "value2"});
    

    Also, you could probably simplify the code using data binding depending on the actual use-case.

    https://ballerina.io/learn/by-example/http-service-data-binding
    https://ballerina.io/learn/by-example/http-client-data-binding

    eg -

    import ballerina/http;
    
    service on new http:Listener(8080) {
        resource function post createUser(@http:Payload json jsonObj) returns json|error {
            http:Client httpEndpoint = check new ("https://test.com/%22");
    
            // Same as
            // json respJsonObj = check httpEndpoint->post("/users", jsonObj, {"header1": "value1"});
            // return respJsonObj;
            return httpEndpoint->/users.post("/users", jsonObj, {"header1": "value1"});
        }
    }
    

    You don't really need the caller, request, response, etc. unless you need to access information/do something you can't do with just data binding. The sample is a bit different from the original one though, because it doesn't set the status code based on the client call, instead it uses 201 (https://ballerina.io/spec/http/#2353-default-response-status-codes).