Skip to content

Upload de Arquivos com GraphQL

Este guia explica como implementar corretamente o upload de arquivos em requisições GraphQL, seguindo as melhores práticas e requisitos necessários.

Requisitos Importantes

Headers Necessários

Para fazer upload de arquivos via GraphQL, é necessário incluir o seguinte header:

js
'Apollo-Require-Preflight': 'true'

Este header é necessário para que o Apollo Server processe corretamente a requisição multipart/form-data que contém os arquivos.

Estrutura da Requisição

O upload de arquivos no GraphQL segue uma estrutura específica usando FormData. A requisição deve conter três partes principais:

  1. Operations: Contém a query/mutation GraphQL e as variáveis
  2. Map: Define o mapeamento entre os arquivos e as variáveis
  3. Files: Os arquivos a serem enviados

Exemplo de Implementação

js
async function uploadFileExample(file) {
  const formData = new FormData();

  // 1. Definir a operação GraphQL
  formData.append(
    'operations',
    JSON.stringify({
      variables: {
        input: {
          files: [null] // Placeholder para o arquivo
        }
      },
      query: `
        mutation($input: YourMutationInput!) {
          result: yourMutation(input: $input) {
            id
            fileName
          }
        }
      `
    })
  );

  // 2. Definir o mapeamento
  const map = {
    "0": ["variables.input.files.0"]
  };
  formData.append('map', JSON.stringify(map));

  // 3. Adicionar o arquivo
  formData.append('0', file);

  // 4. Enviar a requisição
  const response = await fetch('https://sua-api.com/graphql', {
    method: 'POST',
    headers: {
      'Apollo-Require-Preflight': 'true',
      'key': '<seu-token>'
    },
    body: formData
  });

  return response.json();
}

// Exemplo de uso
const file = new File([''], 'exemplo.pdf', { type: 'application/pdf' });
uploadFileExample(file);
python
import requests
import json

def upload_file_example(file_path):
    # 1. Preparar o arquivo
    files = {
        '0': ('document.pdf', open(file_path, 'rb'), 'application/pdf')
    }
    
    # 2. Preparar a operação GraphQL
    operations = {
        'variables': {
            'input': {
                'files': [None]  # Placeholder para o arquivo
            }
        },
        'query': '''
            mutation($input: YourMutationInput!) {
              result: yourMutation(input: $input) {
                id
                fileName
              }
            }
        '''
    }
    
    # 3. Preparar o mapeamento
    map = {
        '0': ['variables.input.files.0']
    }
    
    # 4. Enviar a requisição
    response = requests.post(
        'https://sua-api.com/graphql',
        headers={
            'Apollo-Require-Preflight': 'true',
            'key': '<seu-token>'
        },
        data={
            'operations': json.dumps(operations),
            'map': json.dumps(map)
        },
        files=files
    )
    
    return response.json()

# Exemplo de uso
upload_file_example('caminho/para/seu/arquivo.pdf')

Detalhes Importantes

Estrutura do Map

O map é um objeto JSON que define como os arquivos enviados serão mapeados para as variáveis da query GraphQL:

json
{
  "0": ["variables.input.files.0"],
  "1": ["variables.input.files.1"]
}
  • As chaves ("0", "1", etc.) correspondem aos nomes dos campos no FormData
  • Os valores são arrays que indicam onde o arquivo deve ser inserido na estrutura de variáveis

Upload de Múltiplos Arquivos

Para enviar múltiplos arquivos, você precisa:

  1. Adicionar múltiplos placeholders null no array de files
  2. Atualizar o map para incluir todos os arquivos
  3. Anexar cada arquivo ao FormData

Exemplo:

js
const formData = new FormData();

// Operations com múltiplos arquivos
formData.append(
  'operations',
  JSON.stringify({
    variables: {
      input: {
        files: [null, null] // Dois placeholders
      }
    },
    query: `...`
  })
);

// Map para múltiplos arquivos
const map = {
  "0": ["variables.input.files.0"],
  "1": ["variables.input.files.1"]
};
formData.append('map', JSON.stringify(map));

// Adicionar os arquivos
formData.append('0', file1);
formData.append('1', file2);

Tratamento de Erros

Alguns erros comuns que podem ocorrer durante o upload de arquivos:

  1. Missing Apollo-Require-Preflight Header

    • Erro: "File upload is not enabled"
    • Solução: Adicionar o header Apollo-Require-Preflight: true
  2. Map Incorreto

    • Erro: "Variables for upload are missing in operation"
    • Solução: Verificar se o mapeamento está correto e corresponde à estrutura das variáveis
  3. Limite de Tamanho

    • Erro: "File is too large"
    • Solução: Verificar os limites de tamanho do servidor e comprimir arquivos se necessário

Melhores Práticas

  1. Validação de Arquivos

    • Verifique o tipo e tamanho dos arquivos antes do upload
    • Implemente tratamento de erros adequado
  2. Feedback ao Usuário

    • Implemente indicadores de progresso para uploads grandes
    • Forneça feedback claro em caso de erros
  3. Segurança

    • Sempre valide os tipos de arquivo permitidos
    • Implemente limites de tamanho apropriados
    • Nunca confie em dados do cliente sem validação
  4. Performance

    • Considere comprimir arquivos grandes antes do upload
    • Implemente upload em chunks para arquivos muito grandes
    • Use streams quando apropriado