spring-graphql icon indicating copy to clipboard operation
spring-graphql copied to clipboard

Add projection support to @GraphQlRepository

Open GoncaloPT opened this issue 3 years ago • 5 comments

For those of us who don't want to use Entity classes in the presentation layer, it would be good to have a way of auto-registering our projections, while still getting all the advantages of auto configuration.

Currently one has to register DataFetchers and Builders in order to be able to use the projectAs() in the builder.

It would be nice to have projectAs in @GraphQlRepository annotation.

Implementation wise doesn't seem a big change:

In here, we would have to check for a projectAs in executors GraqlRepository annotation and use it in the build.projectAs

What are your thoughts on this? I can do the change if it is seen as a good one.

--

After implementing it on my side, this creates an awful dependency from datalayer/repositories into presentation layer, since we would have to declare - in our repository - something like: @ProjectedGraphqlRepository(typeName = "AreaType", projectAs = Area.AreaType.class).

Maybe a better way would be to register some kind of ProjectionResolvers that would map entities to projections.

GoncaloPT avatar Sep 07 '22 15:09 GoncaloPT

What do you want to achieve with interface projections for query results? The GraphQL engine doesn't care whether an object is an interface or an object type.

Can you provide a bit of sample code showing the problem you want to solve?

mp911de avatar Sep 15 '22 07:09 mp911de

Hi @mp911de I've meanwhile develop my "own solution" since i couldn't wait.

I will show you how I'm using it before discussing how I've implemented it ( It is hacky right now since many of the configuration classes in spring-graphql are private/package default so I had to copy them into my project 😢 - but the principles are quite simple )

So what I have in my projection interfaces ( that I use in the presentation/graphql ) is:

@GraphQlRepositoryProjection(forRepository = CheckTypeRepository.class)
interface CheckType {
    String getCheckTypeId();
    String getCode();
}

This annotation is used to mark the relationship between an executor and a projection. With this marker, I can register projections for specific executors automatically.

What this achieves is the autoregistration of these projections without having to write any data fetcher code, it works out of the box.

If you find this idea useful we can discuss it further in terms of implementation; it will require a new annotation, like 3 lines of change in the DataFetcher classes (by example and dsl ) and some change over the spring.boot autoconfiguration part to include a ProjectionsResolverSupplier ( which will provide the annotation|executores map )

GoncaloPT avatar Sep 15 '22 13:09 GoncaloPT

I still miss what problem you're trying to solve. Can you elaborate on why you're using interface projections in the first place?

GraphQL repositories fetch only the properties that are requested in the field selection which makes simple interface projections pointless.

mp911de avatar Sep 16 '22 09:09 mp911de

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

spring-projects-issues avatar Sep 23 '22 09:09 spring-projects-issues

Hi @mp911de . Simple projections are not pointless since i can use @Value annotations to map entity fields to the actual graphql fields. They are very useful and I've been using that a lot, without losing all the goodies @GraphqlRepository gives me.

For instance, imagine that you have a Person and a SpecialPerson 1 to 1 relation in your database, but your consider this an implementation detail that you want to hide. I can have my graphql model only with SpecialPerson type, and use @Value in the projection to fetch fields from both Person and SpecialPerson tables. This is just an example and not the full extent of usage of projections in graphql regard..

GoncaloPT avatar Sep 23 '22 15:09 GoncaloPT

After a discussion, we've decided to provide a way to customize the settings for auto-registered repositories, see #531.

rstoyanchev avatar Nov 10 '22 11:11 rstoyanchev