-
Notifications
You must be signed in to change notification settings - Fork 49
server_migrate_1 x_to_2 x
- Introduction
- Changes that impact the existing code
- Other changes
- Other changes, for information
- TODO : re-write this part
- Step to remove the DataFetchers
- Current step
- GraphQLServerMain
- CustomGraphQLController
- RuntimeWiring
- DataLoader
- TypeResolver
Work in progress (2.x is about to be released)
TODO - The plugin parameters are still the same as in the 1.x release. This will chang before the first official release, that is: the following parameters will be removed.
- copyRuntimeSources: will be forced to false
- generateBatchLoaderEnvironment: will be forced to true (server only)
- generateDeprecatedRequestResponse: will be forced to false (client only)
- separateUtilityClasses: will be forced to true (both client and server mode)
- skipGenerationIfSchemaHasNotChanged: will be forced to true (both client and server mode)
This page describe how to migrate a server implementation from a 1.x version to the last 2.x version.
If you're looking for a migration of the client implementation, please check the Client migration from 1.x to 2.x
The 2.x version is based on spring-graphql. Spring and spring-graphql are responsible for the whole transport part. The first versions are a mostly a port to use spring-graphql, with the lower impact possible on your exiting code.
As the generated code is based on spring-graphql, spring dependencies are mandatory. spring-graphql doesn't choose between spring-mvc and spring-WebFlux. But the implementation that is done, based on spring-graphql, must choose between these two.
The generated code is based on Spring WebFlux.
As a consequence, in 2.x, the following dependencies are not needed by the generated code:
- activation and spring-boot-starter: they are no more directly needd.
- graphql-java-spring-mvc (the applications are now web flux apps)
- spring-boot-starter-websocket (the Web Socket protocol is managed directly by
spring-boot-starter-graphql)
In 1.x versions, the plugin allows to define the GraphQL endpoint's path with the graphql.url entry in the Spring configuration file (application.yml or application.properties)
For servers only, in 2.x releases, this configuration is manager by spring. So the relevant configuration entry becomes spring.graphql.path in the Spring configuration file. For instance, for an application.properties file:
spring.graphql.path=/another-graphql-endpoint-path
In both 1.x and 2.x releases, the default value is /graphql
Like stated in the spring-graphql project, you can register a DataFetcherExceptionResolverAdapter that allows proper Exception management in your GraphQL server. There is a sample in the provided graphql-maven-plugin-samples-allGraphQLCases-server sample module. You just have to create a subclass of DataFetcherExceptionResolverAdapter, and override one of the resolveToSingleError or resolveToMultipleErrors methods.
Don't forget to add the @Component annotation, to register it.
It is undocumented, but the same mecanism exists for subscriptions exceptions. The class to override is SubscriptionExceptionResolverAdapter.
The web socket transport is mandatory for subscription. To allow it, a line like this must be added in the application.properties (or application.yml ) file:
spring.graphql.websocket.path=/graphql
The schema files are copied to the default spring-graphql folder (that is: the ./graphql folder in the classpath), as this is the default path wher spring-graphql looks for the GraphQL schema file.
RSocket is also supported (see the spring-graphql doc for more information on how to do this)
The main change between the original graphql-java implementation and the Spring logic is the way to wire the Data Fetchers to the GraphQL engine.
- In 1.x branch (with graphql-java), this was done in the generated
GraphQLWiringclass. It used to wire the code for custom scalars and all GraphQL type, unions... Then, theGraphQLDataFetchersclass would wire eachDataFetcherDelegateXxxxmethod to the relevant non-scalar field. - spring-graphql uses a different logic:
* The
GraphQLWiringspring component still exists. But it only wires the custom scalar implementations. The custom scalars to use are declared in the plugin configuration, that in the pom.xml or build.gradle file, like in 1.x releases. * The Controllers: GraphQL web applications must declare a Controller for each GraphQL object, union... This is done by classesXxxxControllerthat are generated by the plugin. These Controllers are responsible for managing each non-scalar field. * To keep compatibility with code written for 1.x releases of the plugin, the plugin generates theseXxxxControllerclasses. They are responsible for calling theDataFetchersDelegateXxxxcomponents (including the BatchLoaders), and then reuse the code written for the 1.x release * It is planned to be able to override the default generated Controllers
In 2.x, it is no more possible to override the GraphQLDataFetchers spring component.
With spring-graphql, the wiring between the GraphQL requests and the server code is done in the Spring Controllers. It is planned to be able to override theses Controllers.
It is possible to define a DataFetcherExceptionResolver. It is a custom Spring component that allows to manage the Exceptions thrown by the application, and define which ones must be sent as GraphQL Errors in the GraphQL response.
The default behavior is to mask them into a generic server error.
You'll find a sample in the graphql-maven-plugin-samples-allGraphQLCases-server module of the 2.x branch. The org.allGraphQLCases.server.config.MyDataFetcherExceptionResolverAdapter checks if the thrown exception is an instance of GraphQlException, that is an Exception defined in this project. If it is the case, then it either maps to a new GraphQLError, or to the actual thrown exception (that implements GraphQLError).
GraphiQL is available in spring-graphql. It is inactive by default.
It can be enabled with the spring.graphql.graphiql.enabled property, to define in the spring configuration file (application.properties or application.yml). It is then available at this path: /graphiql.
So there is no more need of the com.graphql-java-kickstart:graphiql-spring-boot-starter dependency.
The spring.graphql.schema.printer.enabled property allows to expose the schema file in text format at /graphql/schema, to define in the spring configuration file (application.properties or application.yml).
The Batch Loader is the capacity to use that is a very important optimization, on server side. You'll find the details in the java dataloader github page and in the graphql-java site.
The plugin doc for this subject is available in this wiki. Whether you use the 1.x and 2.x version of the plugin, your code implementation is the same.
What's change here is the way the plugin wires the Batch Loader method. With spring-graphql, the Batch Loader method are registered in a Spring BatchLoaderRegistry, within the constructor of the generated Controller, when needed. You'll find samples of that in the code generated for the graphql-maven-plugin-samples-Forum-server sample, for instance the TopicController.
Adding Relay Connection capability to a GraphQL schema
Creating a first app (non spring)
Connect to more than one GraphQL servers
Easily execute GraphQL requests with GraphQL Repositories
Access to an OAuth2 GraphQL server
How to personalize the client app
Howto personalize the generated code
Client migration from 1.x to 2.x
Implement an OAuth2 GraphQL server
Howto personalize the generated code