REST API with Non-Blocking Embedded Resources

81 views Asked by At

I'm working on a REST API and, for the collection endpoint, would like the _embedded array to asynchronously populate. Unfortunately, I can't seem to puzzle out how to do this while also having the _links element in place. Placing a Publisher at the top level of the response properly asynchronously returns values; placing a Publisher inside the embedded object causes an error upon serialization.

This is the current (not working) code. I'm using Project Reactor and Micronaut.

    @Get
    HttpResponse<Publisher<Response>> get() {
        Response response = new Response();
        response.embedded("item", new FluxEmbed(Flux.just(1, 2, 3, 4, 5)));
        response.link("index", "example.org");

        return HttpResponse.ok(Mono.just(response));
    }

    @Serdeable.Serializable
    class Response extends AbstractResource<Response> {
    }

    @Serdeable.Serializable
    class FluxEmbed extends AbstractResource<FluxEmbed> {
        private final Publisher<Integer> publisher;

        public FluxEmbed(Publisher<Integer> publisher) {
            this.publisher = publisher;
        }

        public Publisher<Integer> getPublisher() {
            return publisher;
        }
    }

The intended behavior would be to have the output of the _embedded array gradually populate. Right now, I can make that happen by performing blocking operations, but I'd prefer to remain in the asynchronus model.

JSON output; _embedded array should populate over time. This can be done if I return a Flux as the body of the HttpResponse, but that doesn't meet HAL standards.

{
  "_links": {
    "index": [
      {
        "href": "example.org",
        "templated": false
      }
    ]
  },
  "_embedded": {
    "item": [
      {
        "value": 1
      }
    ]
  }
}
0

There are 0 answers