GraphQL côté front-end avec Vue.js : sécurité automatique des types grâce à Codegen

26 mai 2026

GraphQL côté front-end avec Vue.js : sécurité automatique des types grâce à Codegen

L’adoption de GraphQL en front-end apporte des bénéfices significatifs lorsqu’il est combiné avec des outils de génération de code. Dans cet article, je vais partager comment nous avons implémenté GraphQL avec Vue.js en utilisant GraphQL Code Generator et Vue Apollo Composable, atteignant une sécurité de type complète et automatique.

Le Problème du Typage Manuel

Dans les applications REST + TypeScript traditionnelles, il est fréquent de maintenir des types en double :

La Solution : GraphQL + Code Generator

GraphQL Code Generator transforme vos requêtes et mutations en code TypeScript entièrement typé, en utilisant le schéma comme source unique de vérité.

Principales Avantages

1. Sécurité de type de bout en bout

2. Détection automatique des changements cassants

3. Productivité accélérée

4. Expérience développeur supérieure

Configuration dans le Projet

1. Mise en place de GraphQL Code Generator

// codegen.ts
import type { CodegenConfig } from '@graphql-codegen/cli'
const config: CodegenConfig = {
  overwrite: true,
  schema: `${process.env.VITE_API_SERVICE_URL}/graphql`,
  documents: ['src/graphql/**/*.gql'],
  generates: {
    'src/generated/graphql.ts': {
      plugins: [
        'typescript',
        'typescript-operations',
        'typescript-vue-apollo'
      ],
      config: {
        withCompositionFunctions: true,
        vueApolloComposableImportFrom: '@vue/apollo-composable',
        vueCompositionApiImportFrom: 'vue',
        skipTypename: true,
        dedupeOperationSuffix: true,
        documentMode: 'documentNode'
      }
    }
  }
}

2. Définition des requêtes GraphQL

# src/graphql/queries/GetProducts.gql
query GetProducts(
  $offset: Int!
  $limit: Int!
  $search: String
  $category: String
) {
  getProducts(
    input: {
      offset: $offset
      limit: $limit
      search: $search
      category: $category
    }
  ) {
    data {
      id
      name
      description
      price
      category
      inStock
      createdAt
    }
    total
  }
}

3. Fichier Généré Automatiquement

Le Code Generator crée des types et des composables prêts à l’emploi :

// src/generated/graphql.ts (gerado automaticamente)
export type GetProductsQueryVariables = Exact<{
  offset: Scalars['Int']['input'];
  limit: Scalars['Int']['input'];
  search?: InputMaybe<Scalars['String']['input']>;
  category?: InputMaybe<Scalars['String']['input']>;
}>;
export type GetProductsQuery = {
  getProducts: {
    data: Array<{
      id: string;
      name: string;
      description?: string | null;
      price: number;
      category: string;
      inStock: boolean;
      createdAt: string;
    }>;
    total: number;
  };
};
export function useGetProductsQuery(
  variables: GetProductsQueryVariables | VueCompositionApi.Ref<GetProductsQueryVariables>,
  options?: VueApolloComposable.UseQueryOptions<GetProductsQuery, GetProductsQueryVariables>
) { /* ... */ }

Utilisation dans le Composant Vue

Voici un exemple réel de l’utilisation des composables générés :

<template>
  <div>
    <SearchInput 
      v-model="searchTerm"
      placeholder="Rechercher des produits..."
    />

    <LoadingSpinner v-if="loading" />

    <ErrorMessage 
      v-if="errorExist"
      message="Impossible de charger les produits"
    />

    <ProductList :products="products" />
  </div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import { useGetProductsQuery } from '@/generated/graphql'
// État réactif
const searchTerm = ref('')
const products = ref([])
const errorExist = ref(false)
// Variables de la requête (réactives)
const queryVariables = computed(() => ({
  offset: 0,
  limit: 20,
  search: searchTerm.value,
  category: 'electronics'
}))
// Composable généré automatiquement avec des types complets
const { loading, onResult, onError } = useGetProductsQuery(
  queryVariables,
  {
    fetchPolicy: 'cache-and-network'
  }
)
// Handlers avec des types inférés automatiquement
onResult((result) => {
  // result.data est totalement typé!
  products.value = result.data.getProducts.data.map(product => ({
    id: product.id,
    title: product.name,
    subtitle: product.description || 'Sem descrição',
    price: product.price,
    available: product.inStock
  }))

})
onError((error) => {
  errorExist.value = true
  console.error('Erreur lors du chargement des produits :', error)
})
</script>

Avantages en pratique

Autocomplétion intelligente

En accédant à result.data.getProducts.data[0]., l’IDE propose uniquement les champs que vous avez demandés dans la requête GraphQL. Si vous tentez d’accéder à un champ non sollicité, une erreur de compilation se produira !

Refactorisation sûre

Vous avez renommé un champ dans le backend ? TypeScript signalera une erreur partout où ce champ est utilisé sur le frontend.

Validation des variables

Les variables de la requête sont validées lors de la compilation. Des types incorrects ou des champs obligatoires manquants provoquent une erreur avant même l’exécution.

Réactivité native de Vue

Les composables générés s’intègrent parfaitement à la Composition API, en prenant en charge ref, computed et toute la réactivité de Vue 3.

Workflow de développement

  1. Le designer crée/met à jour la requête GraphQL dans .gql
  2. Lancement du codegen : npm run codegen
  3. Importation du composable généré dans le composant
  4. TypeScript garantit que tout est correct
  5. L’IDE offre l’autocomplétion complète

Mutations avec sécurité de type

Le même principe vaut pour les mutations :

<script setup lang="ts">
import { useCreateProductMutation } from '@/generated/graphql'
const { mutate: createProduct, loading, onDone } = useCreateProductMutation()
const handleSubmit = async (formData) => {
  await createProduct({
    input: {
      name: formData.name,
      price: formData.price,
      // TypeScript valide tous les champs !
    }
  })
}
onDone((result) => {
  // Résultat tout à fait typé
  console.log('Produit créé :', result.data.createProduct.id)
})
</script>

Conclusion

La combinaison de GraphQL + Code Generator + Vue Apollo Composable offre :

Zéro effort manuel pour maintenir les types synchronisés
Détection automatique des changements cassants
Expérience développeur supérieure avec autocomplétion complète
Sécurité de type de bout en bout du backend à l’UI
Intégration parfaite avec Vue 3 Composition API
Moins de bugs en production

Si vous utilisez GraphQL en front-end sans code generator, vous ratez l’un des plus grands avantages de cette technologie. La productivité et la sécurité qu’offre cette stack transforment complètement le développement d’applications modernes.

Fabien Delpont

Auteur

Fabien Delpont

Fabien Delpont, développeur et créateur du site Python Doctor.