Résolution des Conflits de Types

Ce guide vous aide à diagnostiquer et résoudre les conflits de types courants dans vos schémas GraphQL générés avec GraphQL AutoGen.


Types de Conflits Courants

Conflit de noms de types

Ce type de conflit se produit lorsque deux ou plusieurs classes Java génèrent des types GraphQL avec le même nom.

Exemple d'erreur
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'graphQLSchema': Type 'User' is already defined

Conflit de définition de champs

Ce conflit survient lorsqu'un champ est défini plusieurs fois avec des types de retour différents.

Exemple d'erreur
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'graphQLSchema': Field 'Product.price' has conflicting type definitions: BigDecimal vs Float

Conflit d'arguments

Ce conflit se produit lorsque les arguments d'une requête ou d'un champ ont des types incompatibles.

Exemple d'erreur
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'graphQLSchema': Argument 'id' of field 'Query.product' has conflicting types: ID vs Long

Solutions pour les Conflits de Noms

1. Renommer avec @GraphQLType

Solution
// Dans le package com.example.user
@Entity
@GraphQLType(name = "AppUser") // Renommé pour éviter le conflit
public class User {
    // ...
}

// Dans le package com.example.auth
@Entity
@GraphQLType(name = "AuthUser") // Renommé pour éviter le conflit
public class User {
    // ...
}

2. Utiliser des espaces de noms

Configuration
# application.properties
graphql.autogen.use-package-namespaces=true

Avec cette configuration, les types seront automatiquement préfixés avec leur nom de package :

Résultat
type User_example_user {
  id: ID!
  username: String!
}

type User_example_auth {
  id: ID!
  email: String!
}

Solutions pour les Conflits de Champs

1. Renommer avec @GraphQLField

Solution
@GraphQLType
public class Product {
    // ...

    @GraphQLField(name = "priceAmount")
    private BigDecimal price;

    // ...
}

2. Exclure le champ problématique

Solution
@GraphQLType
public class Product {
    // ...

    @GraphQLIgnore
    private BigDecimal price;

    @GraphQLField(name = "price")
    public Double getPriceAsDouble() {
        return price != null ? price.doubleValue() : null;
    }

    // ...
}

Solutions pour les Conflits d'Arguments

Corriger le type d'argument

Solution
@RestController
public class ProductController {

    @GraphQLQuery(name = "product")
    public Product getProductById(@GraphQLArgument(name = "id", type = "ID") String id) {
        // Conversion en Long si nécessaire
        return productService.findById(Long.valueOf(id));
    }
}

Stratégies Avancées

Segmentation par modules

Pour les applications plus grandes, envisagez de segmenter votre schéma GraphQL par domaines fonctionnels :

Configuration multi-schémas
# application.properties
graphql.autogen.schemas[0].name=productSchema
graphql.autogen.schemas[0].base-package=com.example.product
graphql.autogen.schemas[0].path=/graphql/product

graphql.autogen.schemas[1].name=userSchema
graphql.autogen.schemas[1].base-package=com.example.user
graphql.autogen.schemas[1].path=/graphql/user

Transformateurs de schéma personnalisés

Créez des transformateurs personnalisés pour résoudre les conflits au moment de la génération :

Transformateur personnalisé
@Component
public class ConflictResolvingTransformer implements GraphQLSchemaTransformer {

    @Override
    public GraphQLSchema transform(GraphQLSchema originalSchema) {
        // Logique personnalisée pour résoudre les conflits
        return SchemaTransformer.newSchema(originalSchema)
            .renameType("User", "AppUser")
            .transformField("Product", "price", field -> field.name("productPrice"))
            .build();
    }
}

Surveillance et Prévention

Tests de schéma

Créez des tests unitaires pour vérifier la validité de votre schéma :

Test JUnit
@SpringBootTest
class SchemaValidationTests {

    @Autowired
    private GraphQLSchema schema;

    @Test
    void validateSchema() {
        SchemaValidator validator = new SchemaValidator();
        List errors = validator.validateSchema(schema);

        assertThat(errors).isEmpty();
    }

    @Test
    void checkForTypeConflicts() {
        // Vérifier spécifiquement les types problématiques connus
        assertThat(schema.getType("User")).isNotNull();
        assertThat(schema.getType("AppUser")).isNotNull();
    }
}

Pour mettre à jour votre application vers de nouvelles versions de GraphQL AutoGen, consultez notre guide de migration.