I am reading set values in a csv file as a stream of records. Instead of converting them to an array of records I want to send the stream as it is in a http response. How can I achieve this?
Ballerina only supports returning sub types of anydata
type in http resources. But you can use the http:Caller
object to add the stream as a mime:Entity
body part in the response.
Lets say you have csv file like this in the resource folder,
name,department
Jo,IT
Jane,IT
Jim,Sales
Kim,Marketing
And you can define the http resource in the service as below,
import ballerina/http;
import ballerina/io;
import ballerina/mime;
string[] arr = [];
type Employee record {|
string name;
string department;
|};
service /api on new http:Listener(8080) {
resource function get employeesAsMime(http:Caller caller) returns error? {
stream<Employee, io:Error?> employees = check getEmployees();
stream<byte[], io:Error?> payload = stream from var employee in employees
select employee.toString().toBytes();
mime:Entity entity = new;
entity.setContentId("employee-stream");
entity.setBody(payload);
http:Response response = new;
response.setBodyParts([entity]);
check caller->respond(response);
}
}
function getEmployees() returns stream<Employee, io:Error?>|io:Error {
return io:fileReadCsvAsStream("./resources/employees.csv");
}
And using the http:Client
you can consume this stream as below,
import ballerina/io;
import ballerina/http;
import ballerina/mime;
public function main() returns error? {
http:Client cl = check new ("http://localhost:8080");
http:Response mimeResponse = check cl->/api/employeesAsMime();
mime:Entity[] bodyParts = check mimeResponse.getBodyParts();
foreach mime:Entity bodyPart in bodyParts {
if bodyPart.getContentId() == "employee-stream" {
stream<byte[], io:Error?> byteArrayStream = check bodyPart.getByteStream();
check from var byteArray in byteArrayStream
do {
io:println(string:fromBytes(byteArray));
};
}
}
}