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);
}
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).