0

I'm in the middle of creating a set of APIs for my Frontend to consume using quarkus-resteasy-reactive and quarkus-rest-client-reactive.

Whilst developing the Resource that would expose the Endpoints, I ran into an issue where the 3rd party Service I was connecting to with my Client kept returning the Transfer-Encoding: chunked HTTP Response Header instead of Content-Length, even though I set the Client to use HTTP 2 via quarkus.rest-client.http2=true in my Project's application.properties. This prevented my Frontend from consuming my APIs, as I was simply returning the Response directly from the 3rd party Service to them and Web Browsers threw a HTTP_2_PROTOCOL Error. For reference, a snippet of my previous code is located below:

// ApiClient.kt

@ApplicationScoped
@RegisterRestClient(configKey = "api")
interface ApiClient {
  @POST
  @Path("/api/file/{fileName}")
  fun getFile(
    @PathParam("fileName") fileName: String,
    @HeaderParam(HttpHeaders.ACCEPT) accept: String
  ): Response
}

// ApiResource.kt

@ApplicationScoped
@Path("/api/third-party-service")
class ApiResource {
  @RestClient
  lateinit var apiClient: ApiClient

  @POST
  @Path("/file/{fileName}")
  fun getThirdPartyFile(
    @RestPath("fileName") fileName: String,
    @RestHeader(HttpHeaders.ACCEPT) accept: String
  ): Response = apiClient.getFile(fileName, accept)
}

At first I simply disabled HTTP 2 capabilities in my Application by setting quarkus.http.http2=false, but then I also tried just dropping the offending HTTP Header and that seems to have worked as well:

// ApiClient.kt

@ApplicationScoped
@RegisterRestClient(configKey = "api")
interface ApiClient {
  @POST
  @Path("/api/file/{fileName}")
  fun getFile(
    @PathParam("fileName") fileName: String,
    @HeaderParam(HttpHeaders.ACCEPT) accept: String
  ): RestResponse<ByteArray>
}

// ApiResource.kt

@ApplicationScoped
@Path("/api/third-party-service")
class ApiResource {
  @RestClient
  lateinit var apiClient: ApiClient

  @POST
  @Path("/file/{fileName}")
  fun getThirdPartyFile(
    @RestPath("fileName") fileName: String,
    @RestHeader(HttpHeaders.ACCEPT) accept: String
  ): RestResponse<ByteArray> { 
    val res = apiClient.getFile(fileName, accept)
    return RestResponse.ResponseBuilder.ok(res.entity, res.mediaType).build()
  }
}

However, I am concerned about what would happen if the File returned from the 3rd party Service gets too large to contain within the Application Container's allotted Memory (I assume what is currently happening is that the Application loads the entire File Response into Memory, before passing it back to the User-Agent). Is mu understanding correct? And if so, is there some in-built mechanism that I can possibly leverage on to avoid the Memory Footprint (if this is indeed what is happening)?

Sean Tay
  • 23
  • 8

0 Answers0