spring-graphql: No ConnectionAdapter IllegalArgumentException for existing Java Connection type
I had been following the development of pagination support in #103.
In my setup, I already had types like PuzzleConnection. Upon updating to the release of spring-graphql that added pagination support, I am now getting exceptions like:
java.lang.IllegalArgumentException: No ConnectionAdapter for: foo.bar.models.puzzles.connections.PuzzleConnection
I looked through the reference and even a bit of the code (the starter/autoconfigure-er) but couldn’t see anything about opting out either entirely or on a case-by-case basis via graphql annotations, or even implicitly opting out such as when it detects that the Edge and Connection types already exist (which might be something worthwhile to add?).
Should I just pin to the prior version until something is implemented? Do you recommend that I do something to prevent ConnectionTypeDefinitionConfigurer from being registered?
Thanks for all your work on spring-graphql!
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 17 (12 by maintainers)
Commits related to this issue
- Improve "Connection" schema type checks ConnectionFieldTypeVisitor now checks the complete structure of Connection, Edge, and PageInfo schema types before decorating a DataFetcher. See gh-709 — committed to spring-projects/spring-graphql by rstoyanchev a year ago
- Improve "Connection" Java type checks ConnectionFieldTypeVisitor now also checks if the container type ends on "Connection", and if so it lets it pass through. See gh-709 — committed to spring-projects/spring-graphql by rstoyanchev a year ago
@mzvankovich yes that is supported.
The snapshot seems to work without changes to our current connection implementations 👍
@blaenk I’ve set the release date for 1.2.1 for June 20. We could decide to release sooner depending on the issues that come in, but it’s good to allow some additional time for feedback, and would be timed with the Boot 3.1.1 release on June 22.
In the mean time, looking at the Boot auto-configuration that installs the
ConnectionAdapter, it’s triggered by the presence ofScrollPositionfrom spring-data-commons. That’s probably on the classpath to get this issue. You could define your ownEncodingCursorStrategy<?> cursorStrategy()bean with a custom, no-opCursorStrategy(as long as it doesn’t supportScrollPosition).Thanks for confirming the fix!
The idea with our pagination support is that you don’t have to implement these types. Instead, you would return the actual result items however they may be represented in your underlying service/data layer, and then configure a
ConnectionAdapteralong with aCursorStrategyto help us turn that transparently tographql.relay.Connection.For example if using Spring Data repositories, you would naturally have
PageorWindowfrom paginated requests, and we support returning those directly from the controller method. They are then transparently adapted tographql.relay.Connectionwith our built-in support, but you can also write aConnectionAdapterfor any other paginated type, essentially some kind of simple container of a List of items along with boolean flags about hasNext and hasPrevious. The benefit is to use simpler (or any) pagination type, and useConnectionAdapterto produce the expected, complete paginated response.This does mean that you would need to change your schema to match the GraphQL Cursor Connection spec, which might not be an option, and this is why we make sure your exiting pagination can continue to work as it did before.
This is just to give you an idea, but have a look around the documentation for more details.
I’ve made a couple of updates, 1) to check the complete structure of a Connection schema type before deciding to apply a
DataFetcherdecorator to adapt its return values tographql.relay.Connection, and 2) at runtime to ignore return values with a name that ends onConnection. This double protection I expect will go pretty far. If you could give those a try with 1.2.1-SNAPSHOT and confirm, that would be much appreciated.It could be opt-in or opt-out, but it makes sense to strengthen checks first, and exhaust our options. In the end, my sense is that we will be able to do without that.