jakartaee / data

Data-API
Apache License 2.0
105 stars 29 forks source link

Repositories types that we'll have support #8

Closed otaviojava closed 2 years ago

otaviojava commented 2 years ago

I'm creating this thread to discuss which repositories we should support, at least in this first version of Jakarta Data.

When I checked the Java solutions broadly spread in the market, I usually saw three repositories types:

CrudOperation

Interface to generic CRUD operations on a repository for a specific type. This one we can see more often on several Java implementations.

E.g.:

Paging

Interface with generic CRUD operations using the pagination feature.

E.g.:

Reactive

Interface for generic CRUD operations on a repository for a specific type. This repository follows reactive paradigms.

E.g.:

Should we follow support those types as well?

We won't discuss the how on this thread but only the repositories types that we should have support on Jakarta Data.

frowe commented 2 years ago

I don't see PageableRepository i/f in JNoSQL?

otaviojava commented 2 years ago

@frowe thanks; indeed, Jakarta NoSQL has a Repository extension to pagination: https://www.jnosql.org/spec/#_repository_2

frowe commented 2 years ago

ah, ok, so not a separate interface.

keilw commented 2 years ago

At least in Jakarta NoSQL Paging is included in a single Repository interface. Leaving aside the exact name (to avoid clashes with annotations) I'm not sure if we need more than one interface at least when it comes to

About Reactive, I'd say NO for the spec as of now, because they all depend on various Reactive Java extensions. And we would not like to have such a dependency in the vendor and project-neutral spec.

Plus for at least Reactive Streams, I would leave that kind of integration to MicroProfile Reactive Streams.

otaviojava commented 2 years ago

@keilw about Reactive, Reactive Streams = The interfaces available in JDK >= 9. On Java 11, it has those interfaces: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/Flow.html

keilw commented 2 years ago

@otaviojava Then which are the repository extensions in Spring, Micronaut etc. that use nothing but the JDK? Neither Spring nor Micronaut seem to use that Flow type, so either the JDK tries to do something the others did better or why is there no ConcurrentFlowRepository etc. in Micronaut, if the type was available since around Java 11, @graemerocher?

dstepanov commented 2 years ago

We should probably define the supported format of the methods like save, update, find etc., and supported return types, which can include the reactive/async type, and by that define a reactive/async method. Repositories are just subsets of those methods.

keilw commented 2 years ago

The problem is, that save, update, find, etc. of each "Reactive*" repository in Spring, Micronaut or others look totally incompatible with each other. <S extends T> Mono<S> save(S entity); returns a Reactor Mono which does not even use any interfaces from the JDK, so it's incompatible with all the others. ReactiveRepository is part of JNoSQL and that's just the right place. Beside the fact, it uses the deprecated JDK Observable,

Reactive Streams does not seem to use the JDK Flow yet, and with very few exceptions, the JDK being more a Reference Implementation itself is not so good at defining abstract APIs and specs that other projects use (just remember Java Util Logging) so unless @graemerocher or @dstepanov can show common denominators of

In fact the totally different structures, entity and return types for each of these reactive or otherwise "new and fancy" extensions to the repository interface is why we probably should have the most basic "tagging interface" like Spring's Repository or Micronaut's GenericRepository because it would be compatible on the most abstract level with reactive extensions while they cannot extend the respective CrudRepository types in either Spring or Micronaut.

At most the AsyncCrudRepository in Micronaut has no major dependencies beside Jakarta Validation (which we could use here if we want) and JDK Concurrency, but even there the question is, how valuable it would be in the API compared to compatible imple,entations, because here means every compatible implementation must implement it.

otaviojava commented 2 years ago

@keilw JNoSQL uses a Observable based on reactivestreams as Microstream does.

graemerocher commented 2 years ago

One comment. I don't think CrudRepository and PageableRepository should be unified into a single interfaces. Some backing databases don't support paging so it doesn't make sense to do so IMO.

If we were to support Reactive then the way to do that would be the Flow API for sure. There are bridges and adapters 2 and from Flow which implementations could use.

otaviojava commented 2 years ago

So, we'll have DataRepository as a parent and the other specializations:

graph TD;
    DataRepository-->CrudOperation;
    DataRepository-->PageableRepository;
    DataRepository-->ReactiveRepository;
keilw commented 2 years ago

Whxy is there a CrudOperation instead of CrudRepository? Anyway the code looks OK although there are still all no-ops.

@graemerocher Agreed about the Flow API but I would rather call that FlowRepository or similar, otherwise it becomes mistaken with all the other implementation-specific Reactive extensions that are found elsewhere and that IMO just cannot be abstracted properly.

graemerocher commented 2 years ago

FlowRepository is fine too