Code Monkey home page Code Monkey logo

graphql-java-generator / graphql-maven-plugin-project Goto Github PK

View Code? Open in Web Editor NEW
117.0 4.0 47.0 86.85 MB

graphql-maven-plugin is a Maven Plugin for GraphQL, based on graphql-java. It accelerates the development for both the client and the server, by generating the Java code. It allows a quicker development when in contract-first approach, by avoiding to code the boilerplate code.

Home Page: https://graphql-maven-plugin-project.graphql-java-generator.com

License: MIT License

Java 99.75% HTML 0.22% Batchfile 0.03%

graphql-maven-plugin-project's Introduction

What is it?

The GraphQL Java Generator makes it easy to work in Java with graphQL in a schema first approach.

This project is a code generator, that allows to quickly develop GraphQL clients and GraphQL servers in java, based on a GraphQL schema.

That is: graphql-java-generator generates the boilerplate code, and lets you concentrate on what's specific to your use case.

  • In client mode : graphql-java-generator generates an executor class for each query, mutation type and/or subscription type. These classes contain the methods to call the queries, mutations and subscriptions. That is: to call the GraphQL server, you just call the relevant method. In client mode, the plugin generates:
    • The POJOs from the GraphQL schema. That is: one class, interface or enum for each item in the provided GraphQL schema file(s)
    • The utility classes that allows you to execute queries, mutations and subscriptions, and to retrieve their result (including the GraphQL response's _extensions field)
    • Support blocking and (since 2.3) reactive (Mono, Flux) queries
    • The support for the full GraphQL specification (relay cursors, subscription, custom scalars, fragment, directive, GraphQL variables, GraphQL alias...).
    • The capability to use bind parameters within your queries, mutations and subscriptions, in an easier way than the GraphQL variables
    • It is based on Spring framework, and since 2.0 on spring-graphql. It still can be used with non-spring apps, as explained in the project's wiki.
    • When used in a spring boot app, each Spring component can be overridden. This allows fine tuning, like connecting to OAuth server, changing the WebClient, and much more
    • Since 1.17, it is possible to execute GraphQL request by just creating a Java interface, no code at all: GraphQL Repositories work almost like Spring Data Repositories. More information in the wiki
  • In server mode : graphql-java-generator generates an almost ready to start GraphQL server. The developer has only to develop the access to the data. That is :
    • The generated code can be packaged either in a jar (starting as a Java application) or a war (starting in a Java container like tomcat or jetty).
    • graphql-java-generator generates the main method (in a jar project) or the main servlet class (in a war project),
    • It generates the POJOs for the provided GraphQL schema file(s).
    • It supports the full GraphQL specification (relay cursors, query/mutation/subscription, custom scalars, fragment, directive, aliases...)
    • The generated code is a Spring boot app (or servlet). You can override every default component, to personalize your server: GraphQL components (add instrumentation, type wiring, field wiring...), HTTP stuff (Spring Security, OAuth, OpenID Connect...) and much more. See the server FAQ for more information on this.
    • Various options allows to personalize the generated code (standard JPA annotations, Java type for ID fields, custom scalars, specific annotations...). See the plugin parameters page for all the goal/tasks and their plugin parameters
    • The developer just has to implement each DataFetchersDelegate, based on the provided interfaces, to provide the access to the data

Other points that are worth to point out:

  • The project is extensively tested:
    • Through unit tests (for the runtime),
    • Through unit and integration tests (for the plugin logic)
    • Through full integration tests: three samples contain both the client and the server parts. Integration tests are run on client side, against "its" server side. More than 250 integration tests are run on client side against the server part.
  • A big effort is done to avoid any impact on your code, when the plugin evolves.
  • A maven/gradle goal/task allows to merge several schemas in one, adding (for instance) relay capability in the generated schema

Two main versions: 1.x and 2.x

The 1.x version:

  • Allows non-spring application either by using the javax.ws.rs.client.Client client, which is deprecated and has been removed in Spring Boot 3
  • Is based directly on graphql-java, and a clone of graphql-java-spring.
  • Is not compatible with Spring Boot 3 and Spring Framework 5

The 2.x version:

Availability: Maven and Gradle

The generator is currently available both as a Maven plugin and as a Gradle plugins.

The plugin documentation is available on this page. It lists all the plugin goals and their parameters. It is valid for both Maven and Gradle.

Maven plugin

The Maven plugin is available in the project (graphql-maven-plugin-project).

The last published version can be found in the Maven Central Repository

Gradle Plugin

Two Gradle plugins are available from the project graphql-gradle-plugin-project.

They offer the exact same functionalities:

The plugin goals/tasks

All maven goals and gradle tasks are described on this page

This plugin contains these goals (Maven) / tasks (Gradle):

  • generateClientCode : this goal generates the client code from the Graphql schema file(s)
  • generateServerCode : this goal generates the server code from the Graphql schema file(s)
  • generatePojo : this goal generates only the java objects that match the provided GraphQL schema. It allows to work in Java with graphQL, in a schema first approach.
  • (deprecated) graphql was the previous main goal. It can generate both the client and the server code, thanks to its mode parameter.
  • merge allows to generate a GraphQL schema file, based on the source GraphQL schemas. It can be used to merge several GraphQL schema files into one file, or to reformat the schema files.

The Documentation

The full documentation is available on the github wiki.

You can also:

Compatibility with GraphQL

This plugin respects all the GraphQL specifications:

  • queries, mutations and subscriptions
  • introspection
  • custom scalars
  • input types
  • interfaces and unions (that are both implemented in Java interfaces into the generated code)
  • directives
  • fragments (global and inline)
  • input parameters (for fields and directives)
  • Use of Bind Parameters to map Java variables with input parameters
  • easy execution of just a query/mutation/subscription (one field of the query, mutation or subscription type) as a standard method call
  • execution of a full GraphQL request, which allows to execute several queries or several mutations at once
  • Management of the GraphQL response's extensions field
  • Comments and description coming from the GraphQL schema are reported in the generated code

Change log

The Change Log is available here

Note for contributors

Branches

Since 01 may 2023, the default branch is the master_2.x branch. It contains all the changes done for the 2.0 version. This branch

The historical branch has been renamed from master to master_1.x branch. This branch is used only for the 1.x maintenance, that is: only major and security issues.

Project organization

All the plugin logic is stored in the graphql-maven-plugin-project project.

The Maven plugin and the Gradle plugin are just wrapper for the plugin logic, available in the graphql-maven-plugin-logic module of the maven project.

If you want to compile the maven project, you'll have to add the lombok.jar file in your IDE. Please see the relevant section, in the Install menu of the https://projectlombok.org/ home page. This very nice tools generates all java boiler plate code, like setters, getters, constructors from fields...

If you use eclipse, please use the code formatter given with the project (file graphql-java-generator (eclipse code formatter).xml at the root of the project). This allows to have the sample code formatting: the code is then homogeneous, and the comparison between versions is simpler. To do this, go to the eclipse preferences, select Java/Code Style/Formatter, and import this file. Then, in the Java/Editor/Save Actions, check the "Perform the selected action on save", "Format source code", "Format all lines", "Organize imports" and "Additional actions" which its default content

License

graphql-java-generator is licensed under the MIT License. See LICENSE for details.

graphql-maven-plugin-project's People

Contributors

agesenm-els avatar amrutprabhu avatar dependabot[bot] avatar dirkmahler avatar dpalmmna avatar etienne-sf avatar gonzalogomezgarcia avatar johanngoltz avatar lighblue avatar manaswinidas avatar mcarleio avatar mjohnston-il avatar patrickp-at-work avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

graphql-maven-plugin-project's Issues

generation fails

I get this error:

14:35:23.803 [main] WARN  org.springframework.context.annotation.AnnotationConfigApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'documentParser': Unsatisfied dependency expressed through field 'documents'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'documents' defined in com.graphql_java_generator.mavenplugin.SpringConfiguration: Unsatisfied dependency expressed through method 'documents' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'resourceSchemaStringProvider' defined in URL [jar:file:/Users/et2448/.m2/repository/com/graphql-java-generator/graphql-maven-plugin-logic/1.6.1/graphql-maven-plugin-logic-1.6.1.jar!/com/graphql_java_generator/plugin/ResourceSchemaStringProvider.class]: Post-processing of merged bean definition failed; nested exception is java.lang.NoSuchMethodError: 'java.lang.String javax.annotation.Resource.lookup()'

with this config:

 <plugin>
        <groupId>com.graphql-java-generator</groupId>
        <artifactId>graphql-maven-plugin</artifactId>
        <version>1.6.1</version>
        <executions>
          <execution>
            <goals>
              <goal>graphql</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <mode>client</mode>
        </configuration>

Missing support for introspection "keywords" e.g. __typename in object response

Hello Etienne,

I have a simple structure like below:
type Query {
getJobs(
filter: _JobFilter
): [Job!]!
}

type Job {
id: ID!
startTime: Long!
endTime: Long!
}

I am trying to format the response of this query as below:
{
getJobs(filter: {
startTime_gt: 0
....
})
{ id
__typename
}
which behaves as expected in GraphQL Playground.
But in client mode, I have the below issue:

com.graphql_java_generator.exception.GraphQLRequestPreparationException: The GraphQL type has no field of name <__typename>
at com.graphql_java_generator.client.GraphqlClientUtils.checkFieldOfGraphQLType(GraphqlClientUtils.java:272)
at com.graphql_java_generator.client.request.Builder.withField(Builder.java:413)
at com.graphql_java_generator.client.request.Builder.withQueryField(Builder.java:665)
at com.graphql_java_generator.client.request.Builder.withQueryResponseDef(Builder.java:602)

Please advise.

Regards,
Amelia

Enum support seems broken

I have following schema:

enum Title {
  DR,
  MR,
  MS,
  MRS
}

type Account {
  id: Int!
}

input SignupForAccountInput {
  title: Title!
}

type Mutation {
  signupForAccount(input: SignupForAccountInput!): Account!
}

When trying to make following request, it fails:

mutation {
  signupForAccount(input: {
    title: MR
  }) {
    id
  }
}

On this code:

  public Object invokeMethod(Method method, Object o, Object... args) {
    try {
      return method.invoke(o, args);
    } catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException var5) {
      throw new RuntimeException("Error when executing the method '" + method.getName() + "' is missing in " + o.getClass().getName() + " class", var5);
    }
  }

The problem is args[0] is "MR", as string, and generated method is void setTitle(Title title). It seems that mapping isn't working correctly with enum type. Couldn't find anything in Issues or in SO, so creating a new one.

Batchloader and Caching

Hi Etienne,

Could it be, that the results of the batchloading are cached?
The second call doesn't stop by in the batchloader function of my delegate.
Is there an annotation I can switch it off with?
Sometimes caching makes sense but in other cases my calls get "Live"-data.

Thanks,
Markus

master will not compile on JDK8

Current master branch will not compile on JDK8 because of use of Class.getPackageName() in class Builder.

Class.getPackageName() came in in JDK9.

Using Class.getPackage().getName() will make backwards compatible to JDK8.

[Minor] jQAssistant warnings on the generated code for client side

My team is using internally the jQAssistant plugin (https://jqassistant.org/) to validate project specific rules (introduction available at: http://jqassistant.github.io/jqassistant/doc/1.8.0/#_introduction) .

While running the jQAssistant analysis on the module that contains the generated code for the client side, we noticed a few warnings - the ones listed below. Although they are just warnings, it could be useful to have them handled in a future version of the plugin.

If needed, we can also prepare a pull request for this. :)

Regards,
Amelia

[WARNING] --[ Constraint Violation ]-----------------------------------------
[WARNING] Constraint: spring-injection:FieldsOfInjectablesMustNotBeManipulated
[WARNING] Severity: MAJOR
[WARNING] Number of rows: 2
[WARNING] Fields of injectable types must not be manipulated, except from constructors.
[WARNING] Message=com.asml.sara.inventory.service.interfaces.graphql.GraphQLController.init(?) writes field 'translator' at line 61, Injectable=com.asml.sara.inventory.service.interfaces.graphql.GraphQLController, Method=void init(), Field=org.neo4j.graphql.Translator translator, LineNumber=61
[WARNING] Message=com.asml.sara.inventory.service.interfaces.graphql.GraphQLController.init(?) writes field 'graphQL' at line 60, Injectable=com.asml.sara.inventory.service.interfaces.graphql.GraphQLController, Method=void init(), Field=graphql.GraphQL graphQL, LineNumber=60
[WARNING] -------------------------------------------------------------------
[WARNING]

[WARNING] --[ Constraint Violation ]-----------------------------------------
[WARNING] Constraint: spring-injection:InjectablesMustNotBeAccessedStatically
[WARNING] Severity: MAJOR
[WARNING] Number of rows: 6
[WARNING] Injectable components must not be accessed from static variables.
[WARNING] Method=void (java.lang.String,java.lang.String,java.lang.Class,java.lang.Class), Field=graphqlClientUtils
[WARNING] Method=void (java.lang.Class,java.lang.String,java.lang.String), Field=graphqlClientUtils
[WARNING] Method=void (), Field=graphqlClientUtils
[WARNING] Method=void (java.lang.String,java.lang.String,java.lang.Class,java.lang.Class), Field=graphqlClientUtils
[WARNING] Method=void (), Field=graphqlUtils
[WARNING] Method=java.lang.String getInputTypeStringValue(java.lang.Object), Field=graphqlUtils
[WARNING] -------------------------------------------------------------------
[WARNING]

[WARNING] --[ Constraint Violation ]-----------------------------------------
[WARNING] Constraint: spring-injection:InjectablesMustNotBeHeldInStaticVariables
[WARNING] Severity: MAJOR
[WARNING] Number of rows: 2
[WARNING] Injectable components must not be held in static variables.
[WARNING] Type=com.graphql_java_generator.client.request.ObjectResponse, Field=graphqlClientUtils
[WARNING] Type=com.graphql_java_generator.client.request.InputParameter, Field=graphqlUtils
[WARNING] -------------------------------------------------------------------
[WARNING]

[WARNING] --[ Constraint Violation ]-----------------------------------------
[WARNING] Constraint: spring-injection:InjectablesMustNotBeInstantiated
[WARNING] Severity: MAJOR
[WARNING] Number of rows: 2
[WARNING] If the constructor of an Injectable is called from another Injectable, then the caller must be a BeanProducer.
[WARNING] Type=com.graphql_java_generator.CustomScalarRegistryImpl, Method=void (), Injectable=com.graphql_java_generator.CustomScalarRegistryImpl
[WARNING] Type=com.graphql_java_generator.client.GraphqlClientUtils, Method=void (), Injectable=com.graphql_java_generator.GraphqlUtils
[WARNING] -------------------------------------------------------------------
[WARNING]

DateTime/OffsetDateTime executor formatting issue

I ran into an issue with how the executor sends a request to a query that requires a DateTime scalar field. the GraphQL query that it's sending doesn't wrap the OffsetDateTime object as a string before sending the query causing the GraphQL endpoint to return an invalid syntax error.

Issues with directives when generating client classes

We're using the Neo4j GraphQL Java library (https://github.com/neo4j-graphql/neo4j-graphql-java) on the server side and from that directives to specify relations:

type Person {
  name: ID!
  born: Int
  actedIn: [Movie] @relation(name:"ACTED_IN"", direction:OUT)
}
type Movie {
  title: ID!
  released: Int
  tagline: String
}
type Query {
    person : [Person]
}

This results in an error during client code generation (using Maven plugin 1.5.0):

The directive named 'relation' could not be found

If we add the directive definition...

directive @relation(
    name: String
    direction: direction
) on FIELD_DEFINITION

enum direction {
    IN
    OUT
}

...to our schema another problem occurs:

Caused by: java.lang.RuntimeException: Error when trying to execute 'getValue' on 'graphql.language.EnumValue': graphql.language.EnumValue.getValue()
    at com.graphql_java_generator.GraphqlUtils.invokeMethod (GraphqlUtils.java:366)
    at com.graphql_java_generator.plugin.DocumentParser.readAppliedDirectives (DocumentParser.java:477)
    at com.graphql_java_generator.plugin.DocumentParser.readFieldTypeDefinition (DocumentParser.java:719)
    at com.graphql_java_generator.plugin.DocumentParser.readField (DocumentParser.java:694)
    at com.graphql_java_generator.plugin.DocumentParser.lambda$readObjectType$12 (DocumentParser.java:534)

Batchloader implementation not called (yet)

Etienne,

Please recall our conversation here.
#58
The part regarding the batchloader.
I know, that I had something working with 1.11.1
This was called.

 @Override
    public List<ShortnameResponseMM> batchLoader(List<Long> keys, BatchLoaderEnvironment batchLoaderEnvironment) {
        List<LocationShortnameDTO> shortnameList = aggregatorLocationService.getLocationShortnamesByLocationIds(keys);
        List<ShortnameResponseMM> result = new ArrayList();
        //code which maps shortnameList into result in the order of keys.
        return result;
    }

But now with 1.11.2 it's not.
I am building with

<generateDeprecatedRequestResponse>false</generateDeprecatedRequestResponse>
<separateUtilityClasses>true</separateUtilityClasses>
<addRelayConnections>true</addRelayConnections>
<generateBatchLoaderEnvironment>true</generateBatchLoaderEnvironment>

I don't see DataFetchersDelegateShortnameResponseMM get called in GraphQLDataFetchers.
Only in BatchLoaderDelegateShortnameResponseMMImpl

I am not sure, where I can use this. The sample code in the javadoc part is not clear to me.
It says

 * &#64;Override
 * public CompletableFuture<List<ShortnameResponseMM>> friends(DataFetchingEnvironment environment, DataLoader<java.lang.Long, ShortnameResponseMM> dataLoader,
 * 		ShortnameResponseMM source) {
 * 	logger.debug("Executing characterImpl.friends, with this character: {}", source.getId().toString());
 * 	List<java.lang.Long> friendIds = graphQLUtil
 * 			.convertListByteArrayToList(characterRepository.findFriendsId(source.getId()));
 * 	return dataLoader.loadMany(friendIds);
 * }

But I don't see CompletableFuture<List> anywhere in the project.

I haven't found the missing link in your sample code or documentation.
Please could you point me into the right direction?

Unknown node type: graphql.language.InputObjectTypeDefinition

I am having troubles generating code in client or server mode for input objects.

This is my input:

input _DataFilter {
    Domain: String
    Domain_in: [String!]
}

and here it's the error message from the plugin:
Unknown node type: graphql.language.InputObjectTypeDefinition InputObjectTypeDefinition{name='_DataFilter', directives=[], inputValueDefinitions=[InputValueDefinition{name='Domain', type=TypeName{name='String'}, defaultValue=null, directives=[]}, InputValueDefinition{name='Domain_in', type=ListType{type=NonNullType{type=TypeName{name='String'}}}, defaultValue=null, directives=[]}]}

Is there a limitation of the plugin around input objects in client mode? Or am I constructing the input wrong?

Any feedback would be appreciated.

Authorization gets lost

We are using Feign to generate our REST clients.

The first call that is triggered in the DataFetchersDelegateQuery implementation works as expected.
A call to SecurityContextHolder.getContext().getAuthentication() returns the bearer string.

But a second call that is triggered in a Non-Root DataFetchersDelegate fails, because the Authorization is empty.
SecurityContextHolder.getContext().getAuthentication() is empty this time.

In the log you can see, that this is the case, once the DataFetcherDelegates is in the onPool worker threads.

Is there a solution to get the UserJWT?
I didn't see it in the DataFetschingEnvironment either and getVariables() is unmutable, so that I cannot pass it.

Thanks a lot,
Markus

Support for nested lists

Our model contains a matrix of Float's represented by a field

type Test {
matrix: [[Float]]!
}

which is valid graphQL schema.

When using the client generator, we get an error:

Case not found (subnode of a ListType). The node is of type graphql.language.ListType (for field matrix)

Without this support, we have to try and make matrix and array of another type which then contains the 2nd array which is not as correct.

Is there some other workaround for nested lists?

Unable to use custom scalar types as input parameter of a query

Hello,

I defined a custom scalar n my shema, but I am unable to use it as quary parameter:

Schema

`scalar Object

type Customer {
refId : String
birthDate : String
}

type Query {
find(client: Object): [Customer]
}
schema {
query: Query
}
`
Object here should be ser / deser as a map, and I used GraphQLScalarType.newScalar() builder to implement the scalar type ser / deser, using Jackon Object mapper.

When I try to fire a query, the serialiazed string of the Object map passed as a param to the query seems to be the result of Map.toString() instead of the json form of the map that should have been issued by the jackson mapper deser.

Am I missing something here?

Thank you.

There is a problem when using Boolean Type with property prefix "is"

graphql sdl:
type Person { isPrimary: Boolean }

It will generate class below:

public class Person  {
	@GraphQLScalar(graphqlType = Boolean.class)
	Boolean isPrimary;
	public void setIsPrimary(Boolean isPrimary) {
		this.isPrimary = isPrimary;
	}
	public Boolean getIsPrimary() {
		return isPrimary;
	}
}

But the correct getter/setter in JAVA is:

        Boolean isPrimary;
        public Boolean getPrimary() {
            return isPrimary;
        }
        public void setPrimary(Boolean primary) {
            isPrimary = primary;
        }

The Getter/Setter method name is wrong.
After my testing, it will ran into a deserialization issue like below in production env.
com.graphql_java_generator.client.response.GraphQLRequestPreparationException: <isPrimary,> is not a valid GraphQL name

refactor generated code for models only option

I ran into some trouble with integration in our codebase, due to the Spring integration features. Fundamentally, Iโ€™m interested in the generated code for the model classes and deserialization only.

That aside, as a proof of concept, Iโ€™ve actually created a variant of your graphql-java-runtime library, with all the client behavior and Spring dependencies stripped out.

How about refactoring the generated code so that users could more easily choose between the options of โ€œmodels onlyโ€ and โ€œfull clientโ€?

-Rick Trotter

How to use variables in filter parameter

I am using GraphQLRequest(graphql-java-generator API) for running GraphQL queries. I have trouble understanding on how to pass parameters in filters(I can pass first and offset as params but not filter params)
Could you please provide an example of how to pass filters with parameters. My example graphql query I am working on is as follows.

{
allMtColumns(first: ?, offset: ?, filter: {
and: {
mtEntityByEntityId: {
mtSchemaBySchemaId: {
name: { equalTo: ?schema}
mtDatabasisByDatabaseId: { name: { equalTo: ?database } }
}
}
}}) {
edges {
node {
name
id
mtEntityByEntityId {
id
name
mtSchemaBySchemaId {
id
name
cqName
type
mtDatabasisByDatabaseId {
id
name
}
}
cqName
}
entityId
cqName
}
}
pageInfo {
endCursor
hasNextPage
hasPreviousPage
startCursor
}
}
}

Generated SubscriptionExecutor doesn't compile

Hi,

Using this graphql schema:

scalar DateTime

input DateTimeFilter {
    eq: DateTime
    le: DateTime
    lt: DateTime
    ge: DateTime
    gt: DateTime
}

type DEntry {
    id: ID!
    type: String
    createdAt: DateTime
    updatedAt: DateTime
    deletedAt: DateTime
    license: String
    source: String
    sourceUrl: String
    sourceId: String
    translationExcerpt: String
}

input DEntryFilter {
    id: [ID!]
    createdAt: DateTimeFilter
    updatedAt: DateTimeFilter
    deletedAt: DateTimeFilter
    and: DEntryFilter
    or: DEntryFilter
    not: DEntryFilter
}

type Subscription {
    getDEntry(id: ID!): DEntry
    queryDEntry(filter: DEntryFilter): [DEntry]
}

When running

mvn clean compile

I get such errors:

[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.028 s
[INFO] Finished at: 2020-12-05T11:29:41+01:00
[INFO] Final Memory: 35M/134M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile (java-compile) on project graphql-maven-bug: Compilation failure: Compilation failure: 
[ERROR] /Users/balazs/Documents/work/sztaki/szotar/sztakidict2020/trials/graphql-maven-bug/target/generated-sources/graphql-maven-plugin/test/client/util/SubscriptionExecutor.java:[611,56] no suitable method found for execute(com.graphql_java_generator.client.request.ObjectResponse,java.util.Map<java.lang.String,java.lang.Object>,com.graphql_java_generator.client.SubscriptionCallback<java.util.List<test.client.DEntry>>,java.lang.String,java.lang.Class<test.client.Subscription>,java.lang.Class<test.client.DEntry>)
[ERROR]     method com.graphql_java_generator.client.QueryExecutor.<R>execute(com.graphql_java_generator.client.request.AbstractGraphQLRequest,java.util.Map<java.lang.String,java.lang.Object>,java.lang.Class<R>) is not applicable
[ERROR]       (cannot infer type-variable(s) R
[ERROR]         (actual and formal argument lists differ in length))
[ERROR]     method com.graphql_java_generator.client.QueryExecutor.<R,T>execute(com.graphql_java_generator.client.request.AbstractGraphQLRequest,java.util.Map<java.lang.String,java.lang.Object>,com.graphql_java_generator.client.SubscriptionCallback<T>,java.lang.String,java.lang.Class<R>,java.lang.Class<T>) is not applicable
[ERROR]       (inference variable T has incompatible equality constraints test.client.DEntry,java.util.List<test.client.DEntry>)
[ERROR] /Users/balazs/Documents/work/sztaki/szotar/sztakidict2020/trials/graphql-maven-bug/target/generated-sources/graphql-maven-plugin/test/client/util/SubscriptionExecutor.java:[694,56] no suitable method found for execute(com.graphql_java_generator.client.request.ObjectResponse,java.util.Map<java.lang.String,java.lang.Object>,com.graphql_java_generator.client.SubscriptionCallback<java.util.List<test.client.DEntry>>,java.lang.String,java.lang.Class<test.client.Subscription>,java.lang.Class<test.client.DEntry>)
[ERROR]     method com.graphql_java_generator.client.QueryExecutor.<R>execute(com.graphql_java_generator.client.request.AbstractGraphQLRequest,java.util.Map<java.lang.String,java.lang.Object>,java.lang.Class<R>) is not applicable
[ERROR]       (cannot infer type-variable(s) R
[ERROR]         (actual and formal argument lists differ in length))
[ERROR]     method com.graphql_java_generator.client.QueryExecutor.<R,T>execute(com.graphql_java_generator.client.request.AbstractGraphQLRequest,java.util.Map<java.lang.String,java.lang.Object>,com.graphql_java_generator.client.SubscriptionCallback<T>,java.lang.String,java.lang.Class<R>,java.lang.Class<T>) is not applicable
[ERROR]       (inference variable T has incompatible equality constraints test.client.DEntry,java.util.List<test.client.DEntry>)

Here's my repo demonstrating this error:

https://github.com/beepsoft/graphql-maven-bug

ExecutionStepInfo Arguments not as Map

Hello Etienne,

Is there a reason, why the arguments in ExecutionStepInfo are LinkedHashMaps and not of the type the plugin generated?
There is no switch, so that I can have them in that way?

Thanks,
Markus

Mapstruct support

Hello Etienne,

I tried to get mapstruct working to translate between the classes the java-generator created and DTO classes that are used to call the services.
Unfortunately that doesn't work as hoped.
The mapstruct-generated Impl-class only calls the builder() of "your" class.
And when I annotate the function with @mapping for the id field, I get a compile error, that that class doesn't have that property.

Do you happen to know if mapstruct and the classes of the graphql-java-generator work together?
And if yes, how?

Kind regards,
Markus

How to change authentication token in request?

I'm trying to create a client that can hit a graphql endpoint that requires an OAuth2 access token in the "Authorization" header of the request.

It seems like I can only do this by calling ClientBuilder.register at the time I create the javax.ws.rs.client. As the client is pretty heavyweight, I'd prefer to only create it once, and change the token before each new request.

Is there some way of changing request headers without creating a new javax.ws.rs.client?

[Update proposal] Extension field in client Error class as Map<String, Object>

Hi,

I propose you to update the "extensions" field in the "com.graphql_java_generator.client.response.Error" class.

The current (june 2018) GraphQL Specification, chapiter "7.1.2 Errors" is talking about the "extensions" field as "This entry is reserved for implementors to add additional information to errors however they see fit, and there are no additional restrictions on its contents."

According to this and as the content of "extensions" is free to the implementors I propose you to update the class with this code :

public Map<String, Object> extensions;

Using "Object" is a "fourre-tout" accroding to "free to the implementors" is easy. Free to the client to know how to cast Object map.

I faced the trouble with this class as error client of a Appollo Server. I had to update the Error class.

Keep me in touch.

CustomScalarTypes do not override graphql types

In my project, I need the Float type to be mapped as a Double for the extra precision.

I updated my pom to have

                   <customScalar>
                        <graphQLTypeName>Float</graphQLTypeName>
                        <javaType>java.lang.Double</javaType>
                        <graphQLScalarTypeStaticField>graphql.Scalars.GraphQLFloat</graphQLScalarTypeStaticField>
                    </customScalar>

But the generated code still has Float as the data.

It appears to be because of the call to fillTypesMap in the parseDocuments method overwriting anything that was set up in the postConstruct method.

It's also interesting that graphql-java expects Float to be a java Double based on the implementation of graphql.Scalars.GraphQLFloat, so maybe the call to
scalarTypes.add(new ScalarType("Float", "java.lang", "Float", pluginConfiguration));
in postConstruct should really be
scalarTypes.add(new ScalarType("Float", "java.lang", "Double", pluginConfiguration));

Proposal for Builder capabilities

This post is obsolete now, as this release has been done. But Dirk proposed another kind of builder, that would be nice to implement. So I keep this thread open

Hello,

I'm working on the next release. The main functional change is the management of GraphQL Fragment in queries.

This has impacts on the existing code. And I want to simplify it, as the client code is too complex.

The result woud be this one :

1) Direct queries would work as before.

2) Prepared queries would work as before
Like:
withOneOptionalParamResponse = queryType.getWithOneOptionalParamResponseBuilder()
.withQueryResponseDef("{id name appearsIn friends {id name}}").build();
...
Character c = queryType.withOneOptionalParam(withOneOptionalParamResponse, character);

3) With Builder queries won't not work any more
For instance, the next lines would not compile:
ObjectResponse characterFriends = new Builder(Character.class, "friends").withField("id").withField("name").build();
withOneOptionalParamResponse = queryType.getWithOneOptionalParamResponseBuilder().withField("id").withField("name").withField("appearsIn").withSubObject(characterFriends).build();
Character c = queryType.withOneOptionalParam(withOneOptionalParamResponse, character);

So my question is:

  • Is any of you is using "with builder" queries ?
  • Is it Ok to remove this capabilty ?

My opinion is that it's much simpler and logical to use the native GraphQL syntax. the withBuilder makes it very complex to build complex queries.
And it's a pain to maintain it.

Etienne

Feature request: add support for directives

Doesn't the graphql-maven-plugin support directives (e.g. https://www.apollographql.com/docs/graphql-tools/schema-directives/) or there is something wrong with the below directive definition?

directive @defer (reason: String = "some reason why") on FIELD

The error message received is:
[ERROR] Failed to execute goal com.graphql-java-generator:graphql-maven-plugin:1.1-SNAPSHOT:graphql (default) on project inventory-generatedmodel: Unknown node type: graphql.language.DirectiveDefinition DirectiveDefinition{name='defer', inputValueDefinitions=[InputValueDefinition{name='reason', type=TypeName{name='String'}, defaultValue=StringValue{value='some reason why'}, directives=[]}], directiveLocations=[DirectiveLocation{name='FIELD'}]} -> [Help 1]
while generating the code in "client" mode.

Any recommendation would be appreciated.

Compile error when CustomScalar has graphQLTypeName different to javaType

I'm using graphql-java-extended-scalars in my project. Here's what I see happening when using them

type TestExtScalar {
bad: NonNegativeInt
}

In the plugin configuration in the pom.xml, I have

<customScalar>
<graphQLTypeName>NonNegativeInt</graphQLTypeName>
<javaType>java.lang.Integer</javaType>
<graphQLScalarTypeStaticField>graphql.scalars.ExtendedScalars.NonNegativeInt</graphQLScalarTypeStaticField>
</customScalar>

The plugin generates the correct CustomScalarDeserializerNonNegativeInt class but in the TestExtScalar, the 'bad' field has an annotation:

@JsonDeserialize(using = CustomScalarDeserializerInteger.class)

which I think should be

   @JsonDeserialize(using = CustomScalarDeserializerNonNegativeInt.class)

Bad type in conditional expression - java.util.UUID cannot be converted to java.util.List<java.util.UUID>

In my graphql schema I have a mutation which receives a list of Ids as args.

type Mutation {
    deleteSnacks(id: [ID]) : Boolean
}

When I run: mvn clean install, it returns the following error:

[INFO] -------------------------------------------------------------<br />
[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] /Users/gustavo/Documents/demo.graphql-plugin-mvn/target/generated-sources/graphql-maven-plugin/com/generated/graphql/GraphQLDataFetchers.java:[132,117] incompatible types: bad type in conditional expression
    java.util.UUID cannot be converted to java.util.List<java.util.UUID>
[INFO] 1 error
[INFO] -------------------------------------------------------------

The following method is generated in GraphQLDataFetchers class:

public DataFetcher<Boolean> dataFetchersDelegateMutationDeleteSnacks() {
		return dataFetchingEnvironment -> {
			List<UUID> id = (dataFetchingEnvironment.getArgument("id") == null) ? null : UUID.fromString(dataFetchingEnvironment.getArgument("id"));
  
			Boolean ret = null;
			try {
				ret = dataFetchersDelegateMutation.deleteSnacks(dataFetchingEnvironment, id);
			} catch (NoSuchElementException e) {
				// There was no items in the Optional
			}

			if (ret != null)
				logger.debug("deleteSnacks: 1 result found");
			else
				logger.debug("deleteSnacks: no result found");

			return ret;
		};
	}

As you can see, the generated method is not fetching the list of UUIDs.

The repo below, reproduces the error:
https://github.com/gusilva/graphql-maven-demo

DataFetchersDelegate for scalar-returning operations

Hello,

Assume you have this model:

type Foo{
   foo(p: String): String
   fu(p: String): Bar
}

If I am right, DataFetcherDelegate classes will only be generated for fu, because it returns an object and not a scalar type.

I would propose an enhancement, that you generate those delegates as well when foo is defined as extension.

extend type Foo{
   foo(p: String): String
}

Without I have to solve it by defining a StringResponse type if I need a newTypeWiring.
You need to know, that I want to work with your generated classes as they are.
Or is it possible to overwrite the GraphQLProvider's buildWiring?

Thanks,
Markus

Use of lombok in generated client POJOs

Hi Etienne,

Do you think it would be a useful feature to be able to configure the client mode to generate POJOs using lombok annotations?

That way we could have builder classes generated for all the POJOs for free.

It would need to be a configuration point in the plugin as clients may or may not be using lombok.

If you think this is a useful feature, I would be prepared to contribute.

Paul

RelayConnection and schema introspection

I'm using version 1.11.2 and am trying to use the RelayConnection directive. Where I use the RelayConnection directive I was expecting the schema to return a Connection type, but it only returns a list of objects.

With server code generated from this schema

directive @RelayConnection on FIELD_DEFINITION

schema {
    query: Query
}

type Query {
    testConnection: [Test] @RelayConnection
}

type Test {
    id: ID!
    name: String
}

I see this in graphiql

image

I thought that maybe it graphiql just showed me the wrong schema, so I tried to run the following query in graphiql

query Test {
  testConnection{
    edges{
      cursor
    }
    pageInfo{
      hasNextPage
    }
  }
}

But then I get these errors

{
  "errors": [
    {
      "message": "Validation error of type FieldUndefined: Field 'edges' in type 'Test' is undefined @ 'testConnection/edges'",
      "locations": [
        {
          "line": 34,
          "column": 5
        }
      ],
      "extensions": {
        "classification": "ValidationError"
      }
    },
    {
      "message": "Validation error of type FieldUndefined: Field 'pageInfo' in type 'Test' is undefined @ 'testConnection/pageInfo'",
      "locations": [
        {
          "line": 37,
          "column": 5
        }
      ],
      "extensions": {
        "classification": "ValidationError"
      }
    }
  ]
}

I was expecting graphiql to say that testConnection returns a TestConnection object. Did I misunderstand how the directive is supposed to work or what it should generate?

Feature request: add support for scalar types e.g. Long

The plugin seems to be missing support for scalar types e.g. Long.

The work-around that my team is currently using was to replace Long with Float in the queries. However it would be nice to have the plugin extended as to support custom scalar types.

Maven plugin is incompatible with Java 11

Hi!

I try to use the plugin with Java 11 (OpenJDK 11.0.2+9), but the error occurs:

Post-processing of merged bean definition failed; nested exception is java.lang.NoSuchMethodError: javax.annotation.Resource.lookup()Ljava/lang/String;

When I run with Java 8 (Oracle Java 1.8.0_162-b12), the plugin works perfectly.

Below is a sample pom.xml that can be used to reproduce the problem. I believe this is connected to having javax.annotation.Resource without lookup() method. But didn't succeed to overcome the problem. Such class exists in javax.annotation:jsr250-api:jar:1.0 which is brought indirectly to the classpath by org.apache.maven:maven-plugin-api:jar:3.6.3. I tried to exclude it from dependencies but this doesn't work.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <artifactId>graphql</artifactId>
    <groupId>sample</groupId>
    <version>1.0-SNAPSHOT</version>


    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <release>12</release>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.graphql-java-generator</groupId>
                <artifactId>graphql-maven-plugin</artifactId>
                <version>1.7.0</version>

                <executions>
                    <execution>
                        <goals>
                            <goal>graphql</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mode>client</mode>
                    <schemaFileFolder>/src/main/graphql</schemaFileFolder>
                    <schemaFilePattern>schema.graphql</schemaFilePattern>
                </configuration>

                <dependencies>
<!--                    <dependency>-->
<!--                        <groupId>org.apache.maven</groupId>-->
<!--                        <artifactId>maven-plugin-api</artifactId>-->
<!--                        <version>3.6.3</version>-->
<!--                        <exclusions>-->
<!--                            <exclusion>-->
<!--                                <groupId>javax.annotation</groupId>-->
<!--                                <artifactId>jsr250-api</artifactId>-->
<!--                            </exclusion>-->
<!--                        </exclusions>-->
<!--                    </dependency>-->
                </dependencies>
            </plugin>
        </plugins>
    </build>

</project>

Question about UUIDs vs Long (javaTypeForIDType)

Hello Etienne,

Our database schema is using Long IDs.
That's why I was setting javaTypeForIDType to true.
But I was wondering, if using random UUIDs is the better option.
Or does this make no sense, if the database/repository doesn't work with UUIDs?

Merci,
Markus

Schema extension support & Syntax error checking

Hello,

  • Does the plugin provide support for schema extension? In graphql-java, we can use extend keyword in SDL to modularise the schema.

The plugin will build the schema below successfully, but the generated code will have compile errors in class GraphQLDataFetchers.

# top.graphqls 
schema {
    query: Query
}

type Query {
    invoicing: Invoicing
}

# domainA.graphqls
extend type Query {
    billing: Billing
}
  • I find that if there are some syntax errors in schema definition, building will still be successful. For example:
# A.graphqls 
type Human {
    id: ID!
    name: String
}

# B.graphqls 
# Conflict definition
type Human {
    friends: [Character]
}

In the process of generating code, can the plugin performs schema syntax checking and exits when syntax errors are found?

Thanks a lot ~

DefaultValue of type graphql.language.BooleanValue is not managed (for field reverse)

I'm trying to run this on shopify's schema, and getting this exception:

[ERROR] Failed to execute goal com.graphql-java-generator:graphql-maven-plugin:1.3.1:graphql (default-cli) on project orbitkit-houston: DefaultValue of type graphql.language.BooleanValue is not managed (for field reverse) -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal com.graphql-java-generator:graphql-maven-plugin:1.3.1:graphql (default-cli) on project orbitkit-houston: DefaultValue of type graphql.language.BooleanValue is not managed (for field reverse)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:956)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:192)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:566)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
Caused by: org.apache.maven.plugin.MojoExecutionException: DefaultValue of type graphql.language.BooleanValue is not managed (for field reverse)
    at com.graphql_java_generator.mavenplugin.GraphqlMavenPlugin.execute (GraphqlMavenPlugin.java:158)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:956)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:192)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:566)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
Caused by: java.lang.RuntimeException: DefaultValue of type graphql.language.BooleanValue is not managed (for field reverse)
    at com.graphql_java_generator.plugin.DocumentParser.readFieldTypeDefinition (DocumentParser.java:562)
    at java.util.stream.ReferencePipeline$3$1.accept (ReferencePipeline.java:195)
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining (ArrayList.java:1654)
    at java.util.stream.AbstractPipeline.copyInto (AbstractPipeline.java:484)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto (AbstractPipeline.java:474)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential (ReduceOps.java:913)
    at java.util.stream.AbstractPipeline.evaluate (AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.collect (ReferencePipeline.java:578)
    at com.graphql_java_generator.plugin.DocumentParser.readField (DocumentParser.java:484)
    at com.graphql_java_generator.plugin.DocumentParser.lambda$readObjectType$4 (DocumentParser.java:368)
    at java.util.stream.ReferencePipeline$3$1.accept (ReferencePipeline.java:195)
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining (ArrayList.java:1654)
    at java.util.stream.AbstractPipeline.copyInto (AbstractPipeline.java:484)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto (AbstractPipeline.java:474)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential (ReduceOps.java:913)
    at java.util.stream.AbstractPipeline.evaluate (AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.collect (ReferencePipeline.java:578)
    at com.graphql_java_generator.plugin.DocumentParser.readObjectType (DocumentParser.java:369)
    at com.graphql_java_generator.plugin.DocumentParser.parseOneDocument (DocumentParser.java:289)
    at java.util.stream.ReferencePipeline$4$1.accept (ReferencePipeline.java:212)
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining (ArrayList.java:1654)
    at java.util.stream.AbstractPipeline.copyInto (AbstractPipeline.java:484)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto (AbstractPipeline.java:474)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential (ReduceOps.java:913)
    at java.util.stream.AbstractPipeline.evaluate (AbstractPipeline.java:234)
    at java.util.stream.IntPipeline.reduce (IntPipeline.java:491)
    at java.util.stream.IntPipeline.sum (IntPipeline.java:449)
    at com.graphql_java_generator.plugin.DocumentParser.parseDocuments (DocumentParser.java:220)
    at com.graphql_java_generator.mavenplugin.GraphqlMavenPlugin.execute (GraphqlMavenPlugin.java:144)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:956)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:192)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:566)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)

The schema was obtained like so:

$ apollo service:download --endpoint=https://orbital-commerce-test.myshopify.com/admin/api/2020-01/graphql.json --header="X-Shopify-Access-Token: <token>"
$ graphql-introspection-json-to-sdl schema.json > schema.graphql

The schema is quite long, but I'll add it here as another comment.

List deserialization issue

Hello,

I am building a very simple client, following the code samples provided with the plugin.
Schema sample below:

schema {
query: QueryType
}
type QueryType {
getAllEquipments(): [MyEquipment!]!
}
interface Equipment {
customerName: String
id: ID!
}
type MyEquipment implements Equipment {
customerName: String
id: ID!
}

The simple query looks like this:
public List< MyEquipment > getAllEquipments() throws GraphQLExecutionException, GraphQLRequestPreparationException {
return queryType.getAllEquipments(/* "{customerName id}" */ "");
}

However I get a deserialization issue related to the list (from what I understand) - stacktrace below:

23:48:54.573 [main] TRACE com.graphql_java_generator.client.QueryExecutorImpl - Generated GraphQL request: {"query":"query {getAllEquipments{ customerName id}}","variables":null,"operationName":null}
com.graphql_java_generator.client.response.GraphQLExecutionException: Error when executing query <{"query":"query {MyEquipment{ customerName id}}","variables":null,"operationName":null}>: Cannot deserialize instance of com.QueryTypeMyEquipment out of START_ARRAY token
at [Source: UNKNOWN; line: -1, column: -1]
at com.graphql_java_generator.client.QueryExecutorImpl.execute(QueryExecutorImpl.java:94)
at com.QueryType.getAllEquipments(QueryType.java:132)
...
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of com.QueryTypeMyEquipment out of START_ARRAY token
at [Source: UNKNOWN; line: -1, column: -1]

Note that I am using the classes for the entities and queries as generated by the plugin version 1.0.0-RC2, I am not changing any class annotation related to serialization.

Any advice would be appreciated.

Amelia

Strings not properly escaped for JSON

I'm trying to use the generated client classes to send strings to a GraphQL endpoint. These string sometimes contain special characters that need to be escaped in JSON, such as TAB, CR, LF. But, they are sent as-is, so the JSON sent to the server is malformed.

For example, in this query

mutation activateMigration {
  activate(activation: {
    tenants: ["	some-string	"]
  })
}

the string contains a TAB character. I would expect the string to be escaped, so that the JSON sent to the server would look like this JSON generated by graphiql:

{"query":"mutation activateMigration {\n  activate(activation: {\n    tenants: [\"\tsome-tenant\t\"]...

but instead, it still contains the TAB characters:

{"query":"mutation activateMigration {\n  activate(activation: {\n    tenants: [\"	some-tenant	\"]...

graphql-java seems to escape all strings according to the JSON rules, as does graphiql. But this library only escapes ". Is this a bug, or working as intended?

Feature request: flexibility in choosing the REST client implementation

Hi Etienne,

We would like to have the flexibility into choosing the REST client implementation.
The reasons for request are as follows:

  • It would enable users the freedom to choose the external dependencies (an alternative to spring-boot-starter-jersey)
  • It would enable users to implement fault tolerance for remote communication.

Regards,
Amelia

Generated clients don't support array field arguments

Given a schema with a type defined as:
type MyType {
id: ID!
name: String!
subObject(types: [SubObjectTypes!]): SubObject
}
where SubObject and SubObjectType (an enum) are also defined.

And a query defined as:
getMyType(id: ID!): MyType

In the generated client for this schema, issuing a query executor request with the following partial query string fails:
String queryString = "{id name subObject(types: [TYPE1, TYPE2])}"
MyType myType = schemaQueryExecutor(queryString, "THE_ID");

The request fails with a GraphQLRequesttPreparationException saying the argument field couldn't be read. If I get rid of the array brackets, and only provide one value (to make the GraphQL client happy with the syntax), the request succeeds.

The generated code for the subObject field likely has these annotations:
@JsonProperty("subObject")
@JsonDeserialize(using = CustomJacksonDeserializers.ListSubObject.class)
@GraphQLInputParameters(names = {"types"}, types = {"SubObjectType"})
@GraphQLNonScalar(fieldName = "subObject", graphQLTypeSimpleName = "SubObject", javaClass = SubObject.class)
I don't see that these annotations indicate that the input parameters will be a list of values.

Log4j dependency

Hello,

The dependency on log4j was previously removed part of the commit 44c65a9 but commit e3c230b re-introduced a dependency on log4j causing conflicts when using other SLF4J backend and force to add an exclusion in the POM / Gradle file.

Feature request: use an abstraction e.g. SLF4J for logging

In version 1.3.1 of the plugin, the generated code has an explicit dependency on LOG4J, which is forcing the clients to use a specific logging framework (which is not ideal).

So our proposal is bind the generated code with the SLF4J API,thus allowing the client to use their preferred logging library ( be it log4j, the Java logging API, or another).

Some online references on this topic:
https://howtodoinjava.com/log4j/slf4j-vs-log4j-which-one-is-better/
https://javapapers.com/java/slf4j-vs-log4j/

Note: if you agree with this proposal, we can also prepare a pull request.

Regards,
Amelia

NoSuchBeanDefinitionException: No qualifying bean of type 'graphql.GraphQL' available:

Hi,
I run into this error when running graphql-java-generator and graphq-java-kickstart. Is there a solution to that? Here is the snippet from my pom.xml

<properties>
	<graphql-maven-plugin.version>1.11</graphql-maven-plugin.version>
</properties>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.4.0</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
/---/
	<dependency>
			<groupId>com.graphql-java-kickstart</groupId>
			<artifactId>graphql-spring-boot-starter</artifactId>
			<version>8.0.0</version>
		</dependency>

		<dependency>
			<groupId>com.graphql-java-generator</groupId>
			<artifactId>graphql-java-runtime</artifactId>
			<version>${graphql-maven-plugin.version}</version>
		</dependency>

[Minor] Unnecessary import in the client generated code

In release 1.3.1 of the plugin, it seems that the client generated code imports exception org.springframework.boot.json.JsonParseException in CustomScalarDeserializer* classes. However this exception is not needed, so I assume it can be safely removed from template client_jackson_deserialize.vm.java?

RelayConnection vs List error

Hello Etienne,

I wanted to test RelayConnection today and facing the following problem

type Query {
  locations(filter: FilterMM): [LocationMM!] @RelayConnection

and in the implementation I am using for testing so far

@Override
public LocationMMConnection locations(DataFetchingEnvironment dataFetchingEnvironment, FilterMM filter) {
    LocationMMConnection result = new LocationMMConnection();
    List<LocationMMEdge> edges = new ArrayList();
    LocationMMEdge edge = new LocationMMEdge();
    edge.setCursor("100149");
    LocationMM locationMM = new LocationMM();
    locationMM.setId(100149L);
    edge.setNode(locationMM);
    edges.add(edge);
    result.setEdges(edges);
    return result;
}

First of all, I am wondering how I get the batchloading hooked up here.

But more urgently: When I call

{
  locations(filter: { businesscaseIds: [1]}
  ){
    id
  }
}

I get the following error
n.graphql.execution.ExecutionStrategy : Can't resolve value (/locations) : type mismatch error, expected type LIST got class de.lsy.cmon.aggregator.graphql.LocationMMConnection

Release 1.0 empty in maven repo

Hi,

We would test your plugin to generate graphql client code but we have a maven dependency problem.

We use the last release (1.0) and we have this error : "Execution default-cli of goal com.graphql-java-generator:graphql-maven-plugin:1.0:graphql failed: Plugin com.graphql-java-generator:graphql-maven-plugin:1.0 or one of its dependencies could not be resolved: Failure to find com.graphql-java:graphql-java-spring-boot-starter-webmvc:jar:2019-11-16T19-22-11-31ab4f9 in https://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced".

When we look in the repo maven we can't find any jar (https://repo1.maven.org/maven2/com/graphql-java-generator/graphql-maven-plugin-project/1.0/).

Is the release 1.0 works and if yes what am I doing wrong ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.