Home / Programação / 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:

Sign Up For Daily Newsletter

Stay updated with our weekly newsletter. Subscribe now to never miss an update!

Deixe um Comentário

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