Exposing view with multiple records as REST API

A common need is to return a collection of multiple row record based on a common field (in this example deal).

Example
arrangementUUID, dealA, otherfield
arrangementUUID, dealA, otherfield
arrangementUUID, dealB, otherfield

The service works correctly when invoked using grpc proxy UI but there are no examples to show how to handle this with the HTTP annotation option (google.api.http).

The HTTP error returned is 503 with this response “upstream connect error or disconnect/reset before headers. reset reason: remote reset”

  rpc GetArrangementsByDeal(ByDealRequest) returns (ByDealResponse) {
    option (kalix.method).view.query = {
      query: "SELECT * AS results FROM arrangements_view WHERE dealId = :dealId"
    };
    option (google.api.http) = {
      get: "/deal/{dealId}/arrangements"
      response_body: "results";
    };
  }

message ByDealRequest {
  string dealId = 1;
}

message ByDealResponse {
  repeated domain.ArrangementState results = 1;
}

If we omit thee optional response_body, I can see this error in the Kalix logs

Error reported from Kalix system: KLX-00608 HTTP API option for [com.example.arrangement.dealview.ArrangementsByDeal.GetArrangementsByDeal] has a response body configured to [*] but that field does not exist

To fix this issue, use a field name defined on the output message type.
Available fields for output type [com.example.arrangement.dealview.ByDealResponse] are:

  • results

At com/example/arrangement/view/view_by_deal.proto:11:1:
service ArrangementsByDeal {
option (kalix.codegen) = {
view: {}
};

rpc OnUpdateState(com.example.arrangement.domain.ArrangementState) returns (domain.ArrangementState) {

It does not matter whether this is a stream or repeated field response. Is there an example of how to handle multi-row?

I don’t see anything obvious that is wrong with that mapping.

I tried reproducing this error, by changing one of the customer-registry-views quickstart views to return a new message with a projected field, and a response body mapping for JSON, like in your problematic case:

message Customers {
  repeated domain.CustomerState customers = 1;
}

service CustomerByEmail {
  ...
  rpc GetCustomer(ByEmailRequest) returns (Customers) {
    option (kalix.method).view.query = {
      query: "SELECT * AS customers FROM customers_by_email WHERE email = :email"
    };
    option (google.api.http) = {
      get: "/customers/by_email/{email}"
      response_body: "customers";
    };
  }
}

But when running that it works fine, so it should work like you expected given that protobuf service descriptor.

I also tried modifying loan application workshop project view to support GET instead of POST and it also works as expected.
I even did not use response_body: "results";
Can you compare this branch with your implementations:

Ok I found the problem. It is the kalix_policy.proto that be default denies all Internet Access. Hence the 503 error that gets returned from the Envoy proxy.

You need to modify by adding option principal: Internet or delete the kalix_policy.proto file from the project.

1 Like