Home / Vuejs / GraphQL no Front-end com Vue.js: Type Safety Automática com Codegen

GraphQL no Front-end com Vue.js: Type Safety Automática com Codegen

vue graphql codegen

A adoção do GraphQL no front-end traz benefícios significativos quando combinado com ferramentas de geração de código. Neste artigo, vou compartilhar como implementamos GraphQL com Vue.js utilizando GraphQL Code Generator e Vue Apollo Composable, alcançando type safety completa e automática.

O Problema da Tipagem Manual

Em aplicações tradicionais REST + TypeScript, é comum manter tipos duplicados:

  • Backend define os tipos
  • Frontend precisa recriar manualmente esses tipos
  • Mudanças no backend exigem atualização manual no front
  • Riscos de inconsistência e erros em runtime

A Solução: GraphQL + Code Generator

GraphQL Code Generator transforma suas queries e mutations em código TypeScript totalmente tipado, usando o schema como fonte única da verdade.

Principais Vantagens

1. Type Safety End-to-End

  • Tipos gerados automaticamente do backend ao frontend
  • Garantias em tempo de compilação
  • Autocomplete completo na IDE

2. Detecção Automática de Breaking Changes

  • Mudanças no schema são detectadas instantaneamente
  • Erros de compilação quando tipos ficam desatualizados
  • Impossível usar campos que não foram solicitados na query

3. Produtividade Acelerada

  • Eliminação de trabalho manual de criar tipos
  • Foco no desenvolvimento da lógica de negócio
  • Composables prontos para uso com reatividade do Vue

4. Developer Experience Superior

  • Documentação inline na IDE
  • Validação em tempo real
  • Redução significativa de bugs

Configuração no Projeto

1. GraphQL Code Generator Setup

// 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. Definindo Queries 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. Arquivo Gerado Automaticamente

O Code Generator cria tipos e composables prontos para uso:

// 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>
) { /* ... */ }


Usando no Componente Vue

Aqui está um exemplo real de como usar os composables gerados:

<template>
  <div>
    <SearchInput 
      v-model="searchTerm"
      placeholder="Buscar produtos..."
    />
    
    <LoadingSpinner v-if="loading" />
    
    <ErrorMessage 
      v-if="errorExist"
      message="Não foi possível carregar os produtos"
    />
    
    <ProductList :products="products" />
  </div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import { useGetProductsQuery } from '@/generated/graphql'
// Estado reativo
const searchTerm = ref('')
const products = ref([])
const errorExist = ref(false)
// Variáveis da query (reativas)
const queryVariables = computed(() => ({
  offset: 0,
  limit: 20,
  search: searchTerm.value,
  category: 'electronics'
}))
// Composable gerado automaticamente com types completos
const { loading, onResult, onError } = useGetProductsQuery(
  queryVariables,
  {
    fetchPolicy: 'cache-and-network'
  }
)
// Handlers com tipos inferidos automaticamente
onResult((result) => {
  // result.data é totalmente tipado!
  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('Error loading products:', error)
})
</script>

Benefícios na Prática

Autocomplete Inteligente

Ao acessar result.data.getProducts.data[0]., a IDE sugere apenas os campos que você solicitou na query GraphQL. Se tentar acessar um campo não solicitado, erro de compilação!

Refatoração Segura

Mudou o nome de um campo no backend? O TypeScript acusará erro em todos os lugares onde aquele campo é usado no front-end.

Validação de Variáveis

As variáveis da query são validadas em tempo de compilação. Tipos errados ou campos obrigatórios faltando = erro antes mesmo de rodar o código.

Reatividade Nativa do Vue

Os composables gerados integram perfeitamente com a Composition API, suportando ref, computed e toda a reatividade do Vue 3.

Workflow de Desenvolvimento

  1. Designer cria/atualiza a query GraphQL em .gql
  2. Roda o codegen: npm run codegen
  3. Importa o composable gerado no componente
  4. TypeScript garante que tudo está correto
  5. IDE oferece autocomplete completo

Mutations com Type Safety

O mesmo vale para 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 valida todos os campos!
    }
  })
}
onDone((result) => {
  // result totalmente tipado
  console.log('Produto criado:', result.data.createProduct.id)
})
</script>

Conclusão

A combinação de GraphQL + Code Generator + Vue Apollo Composable oferece:

✅ Zero esforço manual para manter tipos sincronizados
✅ Detecção automática de breaking changes
✅ Developer Experience superior com autocomplete total
✅ Type safety end-to-end do backend ao UI
✅ Integração perfeita com Vue 3 Composition API
✅ Menos bugs em produção

Se você usa GraphQL no front-end sem code generator, está perdendo uma das maiores vantagens da tecnologia. A produtividade e segurança que essa stack oferece transformam completamente o desenvolvimento de aplicações modernas.

Quer saber mais?

Marcado:

Deixe um Comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Newsletter

Receba semanalmente as novidades do mundo tech

Não fazemos spam! Leia nossa política de privacidade para mais informações.

Receba semanalmente as novidades do mundo tech

Não fazemos spam! Leia nossa política de privacidade para mais informações.