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.
- Envie a foto e o preset desejado e receba de volta um identificador de job.
- Acompanhe o job, por polling ou assinando eventos.
- Baixe a imagem pronta quando o job reportar sucesso.
- 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