Skip to content

usage_schema_personalization

etienne-sf edited this page Aug 28, 2024 · 13 revisions

Schema Personalization

Presentation

With the schema personalization, you can:

  • Personalize the generated classes, interfaces and enums that are generated for types, input types, interfaces, unions and enums:
    • Add one or more interfaces, to the implemented interfaces generated by the plugin
      • interfaces can be added to types, input types, enums, interfaces and unions.
    • Add one or more annotations, to the annotations generated by the plugin
      • annotations can be added to fields, types, input types, enums, interfaces and unions.
    • Add one or more fields (=attribute)
  • Personalize the attributes (use it with caution, as you can break the GraphQL behavior)
    • Define the attribute java type
    • Define whether a field is an id or not (which will trigger the @Id and @GeneratedValue annotation)
    • Define whether this field is a list or not (if true the attribute is a list of the give type, otherwise it's just an instance of this type)
    • Define if this field is mandatory or not
    • Add one or more annotations, to the annotations generated by the plugin

The JSON schema for the schema personalization JSON is available in git. This define the format that your configuration file must respect.

You'll find samples files in the test resources of the plugin project. Of course, the xxx\xxx_KO_xxx files are bad samples as they are used to check the plugin's behavior when the provided file is invalid... ;-)

Available for both client and server mode

Since the 2.2 release:

  • This is also available for client mode (whereas, before, it was available only for the server mode)
  • The replaceAnnotation capability is no more available, as it would break the plugin's behavior

How to configure the plugin

To configure the way the code is generated, you'll have to define a json file that respects the personalization JSON schema.

Then you declare where to find this json file in the pom or gradle file, by using the schemaPersonalizationFile tag:

A sample for Maven:

<project ...>
...

	<build>
		<plugins>
...
			<plugin>
				<groupId>com.graphql-java-generator</groupId>
				<artifactId>graphql-maven-plugin</artifactId>
				<version>2.8</version>
				<executions>
					<execution>
						<goals>
							<goal>graphql</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<mode>client</mode>
					<packageName>my.target.package</packageName>
					<schemaPersonalizationFile>src/main/graphql/forum_personalization.json</schemaPersonalizationFile>
				</configuration>
			</plugin>
...
		</plugins>
	</build>
...
</project>

A sample for Gradle:

generateServerCodeConf {
...
	schemaPersonalizationFile = "src/main/graphql/forum_personalization.json"
...
}

In thes samples, the personalization file is stored in a dedicated folder, instead of the resource. It avoids to add this compile time file into the packed artefact.

But you can keep this file in the resource file, if you want to avoid creating an additional folder, that perhaps you'll forget.

Java class (Entity) personalization

You'll find below some samples of what's possible, and how to do it. Of course, you can mix all these possibilities in one json file.

{
	"entityPersonalizations": [
		{
			"name": "[enums]",
			"addAnnotation": "@org.allGraphQLCases.annotation.AllEnums1(\"enum1\")\n@org.allGraphQLCases.annotation.AllEnums2(\"enum2\")"
		},
		{
			"name": "[input types]",
			"addInterface": "org.allGraphQLCases.interfaces.AllInputTypes1,org.allGraphQLCases.interfaces.AllInputTypes2"
		},
		{
			"name": "[interfaces]",
			"addInterface": "org.allGraphQLCases.interfaces.AllInterfaces1,org.allGraphQLCases.interfaces.AllInterfaces2"
		},
		{
			"name": "[types]",
			"addInterface": "org.allGraphQLCases.interfaces.AllTypes1,org.allGraphQLCases.interfaces.AllTypes2"
		},
		{
			"name": "[unions]",
			"addInterface": "org.allGraphQLCases.interfaces.AllUnions1,org.allGraphQLCases.interfaces.AllUnions2"
		},
		{
			"name": "Human",
			"addAnnotation": "@org.allGraphQLCases.annotation.MyAdditionalAnnotation",
			"addInterface": "org.allGraphQLCases.interfaces.HumanInterface",
			"newFields": [
				{
					"name": "age",
					"type": "Int",
					"id": false,
					"list": false,
					"mandatory": false,
					"addAnnotation": "@org.allGraphQLCases.annotation.LocalAnnotation(\"age\")"
				},
				{
					"name": "age2",
					"type": "Int",
					"id": false,
					"list": true,
					"mandatory": true,
					"addAnnotation": "@org.allGraphQLCases.annotation.LocalAnnotation(\"age2\")"
				}
			]
		},
		{
			"name": "Droid",
			"addAnnotation": "@org.allGraphQLCases.annotation.MyReplacementAnnotation",
			"addInterface": "org.allGraphQLCases.interfaces.AllTypes1,org.allGraphQLCases.interfaces.AllTypes2",
			"fieldPersonalizations": [
				{
					"name": "id",
					"addAnnotation": "@org.allGraphQLCases.annotation.LocalAnnotation(\"local annotation\")"
				},
				{
					"name": "name",
					"addAnnotation": "@org.allGraphQLCases.annotation.LocalAnnotation(\"an annotation\")"
				}
			],
			"newFields": [
				{
					"name": "age",
					"type": "Int",
					"id": false,
					"list": false,
					"mandatory": false,
					"addAnnotation": "@org.allGraphQLCases.annotation.MyReplacementAnnotation"
				}
			]
		},
		{
			"name": "DroidInput",
			"addInterface": "org.allGraphQLCases.interfaces.DroidInputInterface"
		},
		{
			"name": "extends",
			"addAnnotation": "@org.allGraphQLCases.annotation.LocalAnnotation(\"enum's annotation\")"
		},
		{
			"name": "AnyCharacter",
			"addAnnotation": "@org.allGraphQLCases.annotation.LocalAnnotation(\"union's annotation\")",
			"addInterface": "org.allGraphQLCases.interfaces.AnyCharacterInterface"
		},
		{
			"name": "Character",
			"addAnnotation": "@org.allGraphQLCases.annotation.LocalAnnotation(\"interface's annotation\")",
			"addInterface": "org.allGraphQLCases.interfaces.CharacterInterface",
			"newFields": [
				{
					"name": "age",
					"type": "Int",
					"id": false,
					"list": false,
					"mandatory": false,
					"addAnnotation": "@org.allGraphQLCases.annotation.LocalAnnotation(\"interface method's annotation\")"
				}
			]
		}
	]
}

You'll find in this sample these capabilities:

  • The name [enums] matches all enumerations defined in the GraphQL schema
  • The name [input types] matches all input types defined in the GraphQL schema
  • The name [interfaces] matches all interfaces defined in the GraphQL schema
  • The name [types] matches all types defined in the GraphQL schema
  • The name [unions] matches all unions defined in the GraphQL schema
  • The json property [addAnnotation] allows to add one or more annotations to this item. This string may contain:
    • One or more annotations. You must provide their full java name, as you currently can't change the imports of this file.
    • EOL character: \n
    • Tabulations, to have a proper text alignement: \t
  • The json property [addInterface] allows to add one or more interfaces to this item. This string may contain:
    • One or more interfaces. You must provide their full java name, as you currently can't change the imports of this file.
    • EOL character: \n
    • Tabulations, to have a proper text alignement: \t
  • The json property [fieldPersonalizations] allows to update fields for this item.
    • In the above sample, annotations are added to the id and name field of the Droid type.
  • The json property [newFields] allows to add one or more fields to this item. Please see the samples above.
Clone this wiki locally