uncloth.app Guias

Como adicionar filtros de fotos adultas ao seu app

Adicionar um filtro de foto adulta a um produto parece um problema de imagem e acaba sendo um problema de encanamento. O trabalho do modelo você compra em uma única chamada. O que consome a sprint é tudo ao redor: uploads que estouram o tempo limite, jobs que terminam quando ninguém está escutando, retries que silenciosamente cobram duas vezes e uma fila de suporte perguntando onde foi parar um resultado. Este guia percorre a integração de ponta a ponta e aponta os lugares onde os times perdem tempo com regularidade.

Do que a integração realmente é feita

Uma API de transformação de fotos é assíncrona por natureza. A geração demora o bastante para que manter uma conexão HTTP aberta seja má ideia: redes móveis caem, load balancers cortam conexões ociosas e os seus próprios timeouts começam a trabalhar contra você. Por isso o formato é sempre o mesmo — você envia o trabalho, recebe um identificador e coleta o resultado depois.

  1. Envie a foto e o preset desejado e receba de volta um identificador de job.
  2. Acompanhe o job, por polling ou assinando eventos.
  3. Baixe a imagem pronta quando o job reportar sucesso.
  4. Trate os caminhos de falha e retry, que é onde mora a maior parte do trabalho real.

Passo um: enviar o job

O envio é uma requisição multipart carregando a imagem, o identificador do preset e uma confirmação de que você tem os direitos e o consentimento para processar a foto. Envie junto uma idempotency key. Esse único header é a diferença entre uma integração limpa e um problema de suporte, e não custa nada adicionar.

curl -X POST https://api.example/api/v1/jobs \
  -H "X-API-Key: $API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -F image=@photo.jpg \
  -F feature=bikini \
  -F consent=confirmed

A resposta traz o identificador do job e seu status inicial. Persista esse identificador junto ao registro do seu usuário ou sessão imediatamente, antes de qualquer outra coisa. Se o seu processo morrer no segundo seguinte, essa linha é a única coisa que permite reencontrar o trabalho.

Passo dois: acompanhar o progresso

Há duas formas de acompanhar um job, e integrações maduras usam as duas. Uma conexão WebSocket entrega mudanças de status e progresso ao vivo, que é exatamente o que você quer alimentando uma barra de progresso na interface. O polling no endpoint do job é o fallback que torna o sistema correto, e não apenas agradável: sockets caem, celulares dormem, e uma consulta a cada poucos segundos custa quase nada.

Trate o WebSocket como otimização e o polling como fonte da verdade. Times que invertem isso acabam com jobs que terminaram perfeitamente no servidor e aparecem travados para sempre no cliente, porque o único evento que importava chegou enquanto o socket reconectava.

Passo três: coletar o resultado

Quando o job reporta sucesso, ele traz uma lista de saídas. Cada saída é obtida com a mesma API key que criou o job, então os resultados nunca são endereçáveis publicamente nem adivinháveis a partir de uma URL. Baixe a imagem para o seu próprio armazenamento assim que recebê-la, se o produto precisar exibi-la depois — uma API de imagens é um serviço de processamento, não uma fototeca, e resultados não são retidos indefinidamente.

Passo quatro: falhas, retries e a armadilha da cobrança dupla

A falha interessante não é aquela em que a API retorna um erro. É a ambígua: sua requisição saiu, a rede caiu e você não faz ideia se o job foi criado. Repita ingenuamente e você pagou duas vezes e produziu dois resultados para uma única ação do usuário.

É isso que a idempotency key resolve. Repita a requisição com a mesma chave e você recebe o job original de volta em vez de um novo, não importa quantas vezes o retry dispare. Gere a chave quando a ação do usuário acontece, guarde-a com o registro do job e reutilize-a em cada retry daquela mesma ação — e não uma chave nova por tentativa, o que anula o mecanismo inteiro.

Onde as integrações costumam travar

  • Validar uploads apenas no cliente. Verifique o arquivo no servidor pelo conteúdo, não pela extensão, antes de gastar uma chamada de API com ele.
  • Construir todo o fluxo de forma síncrona e só então descobrir que clientes móveis derrubam a conexão muito antes de a geração terminar.
  • Tratar o WebSocket como único canal de progresso, sem fallback de polling.
  • Não armazenar nada localmente, de modo que um restart perde o vínculo entre seus usuários e os jobs em andamento.
  • Esquecer que os resultados são transitórios e esperar que a API funcione como armazenamento permanente.

Uma ordem de trabalho sensata

Passe uma foto por todo o caminho com curl antes de escrever qualquer código de aplicação — enviar, consultar, baixar. Depois ligue essas mesmas quatro chamadas ao seu backend, com persistência. Adicione o WebSocket por último, puramente como melhoria de barra de progresso sobre um sistema que já funciona sem ele. Nessa ordem a integração leva um dia; na ordem inversa, leva duas semanas de depuração.

Perguntas frequentes

Quanto tempo leva uma requisição?

A geração é assíncrona e conclui em segundo plano. Projete a interface em torno de um estado de progresso, e não de uma chamada bloqueante, e a duração exata deixa de importar para a sua arquitetura.

Preciso de WebSocket para usar a API?

Não. Tudo funciona apenas com REST. O WebSocket existe para deixar o progresso ao vivo; o polling no endpoint do job dá a mesma informação.

O que acontece se eu enviar a mesma requisição duas vezes?

Com a mesma idempotency key você recebe o job original de volta, e nenhuma segunda geração é produzida nem cobrada.

Construa com a uncloth.app

Um endpoint REST, onze presets, resultados entregues ao seu backend. Conte o que você está construindo e enviaremos os dados de acesso.

Solicitar acesso

Todos os guias