Search code examples
javamicroserviceslagom

Fetching a list with Lagom framework


I'm VERY new to Lagom framework and I have absolutely no idea what I'm doing. I have a simple CRUD lagom application that does work, but I can't figure out how to retrieve a list.

So this is what I have for now, but I'm getting

@Override
    public ServiceCall<NotUsed, Source<Movie, ?>> getMovies() {
        return request -> {
            CompletionStage<Source<Movie, ?>> movieFuture = session.selectAll("SELECT * FROM movies")
                    .thenApply(rows -> rows.stream()
                    .map(row -> Movie.builder()
                        .id(row.getString("id"))
                        .name(row.getString("name"))
                        .genre(row.getString("genre"))
                        .build()));
                    //.thenApply(TreePVector::from));
                    //.thenApply(is -> is.collect(Collectors.toList()))

            return movieFuture;
        };
    }

but I'm getting a [Java] Type mismatch: cannot convert from Stream<Object> to Source<Movie,?> error on the rows.stream() line.

Any help would be appreciated.

Thanks in advance.


Solution

  • It looks like the return type should be a Source (from Akka Reactive Streams) but you are building a Java 8 Stream.

    The problem can be easily solved if you used select instead of selectAll when querying the database. Lagom's CassandraSession provides two families of meqthods to query the DB: (1) select(...) will immediately return a Source<Row,NotUsed> which is a reactive stream or (2) selectAll(...) which will gather all rows in memory and return a List<Row>. The latter could take your server down because will try to put all the info in memory. The former will use reactive streams to deliver items adapting the speed to your consuming end speed (backpressure) keeping a very low memory footprint.

    Your code can be rewritten as:

     public ServiceCall<NotUsed, Source<GreetingMessage, ?>> getGreetings() {
        return request ->
             CompletableFuture.completedFuture(
                  session.select("SELECT * FROM greetings")
                         .map(row -> new GreetingMessage(row.getString(0)))
              );
     }
    

    Using select creates a Source<>. You can map items individually on that Source<> using the lambda you already developed.