uncloth.app 指南

如何在应用中接入成人照片滤镜

给产品接入成人照片滤镜 API,看上去是个图像问题,实际是个管道问题。模型部分一次调用就买到了,真正吃掉整个迭代周期的是它周围的一切:超时的上传、完成时没人在监听的任务、悄悄让你被计费两次的重试,还有追问结果去哪了的工单。本文完整走一遍集成流程,并指出团队最容易浪费时间的地方。

这个集成到底由什么组成

图像转换 API 天然是异步的。生成耗时足够长,为它一直挂着 HTTP 连接并不明智:移动网络会断、负载均衡会掐掉空闲连接、你自己的请求超时也会反过来跟你作对。所以形态永远一样——提交任务、拿到一个标识、之后再来取结果。

  1. 提交照片和所需预设,拿回任务 ID。
  2. 通过轮询或订阅事件来跟踪任务。
  3. 任务返回成功后拉取生成好的图片。
  4. 处理失败和重试路径——真正的工作量都在这里。

第一步:提交任务

提交是一个 multipart 请求,携带图片、预设标识,以及你已获得处理该照片的权利与同意的确认。请顺带发送一个幂等键。这一个请求头就是「干净集成」和「工单事故」之间的分界线,而加上它的成本为零。

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

响应里带有任务 ID 和初始状态。请立刻把这个 ID 落库、关联到你自己的用户或会话记录上,先于任何其他动作。如果进程下一秒就挂了,这行记录是你唯一能重新找回这份工作的线索。

第二步:跟踪进度

跟踪任务有两条路,成熟的集成两条都用。WebSocket 连接提供实时状态变更和进度,这正是驱动界面进度条所需要的。轮询任务接口则是兜底手段,它让系统从「体验好」变成「结果正确」:socket 会断、手机会休眠,而每隔几秒轮询一次几乎不花钱。

把 WebSocket 当成优化,把轮询当成事实来源。把这两者搞反的团队,最后会遇到任务在服务端明明早已完成、客户端却永远卡住的情况——因为那条唯一重要的事件,恰好在 socket 重连时到达。

第三步:取回结果

任务返回成功时会带上输出列表。每个输出都用创建该任务的同一个 API Key 去拉取,所以结果永远不可公开访问,也无法靠猜 URL 得到。如果你的产品之后还要展示它,请在收到时就下载到自己的存储——图像 API 是处理服务,不是相册,结果不会被无限期保留。

第四步:失败、重试与重复计费陷阱

值得关注的失败不是 API 明确返回错误的那种,而是含糊的那种:请求已经发出去了,网络断了,你根本不知道任务有没有被创建。此时天真地重试,你就付了两次钱,并为用户的一次操作产出了两份结果。

这正是幂等键要解决的问题。用同一个键重复请求,拿回的是原来那个任务而不是新任务,无论重试触发多少次。请在用户操作发生时生成这个键、和任务记录一起存下来,并在该操作的每次重试中复用它——而不是每次尝试都新生成一个,那等于把整个机制废掉。

集成通常卡在哪里

  • 只在客户端校验上传。在花掉一次 API 调用之前,先在服务端按文件内容而非扩展名做校验。
  • 把整个流程做成同步的,然后才发现移动端在生成完成之前早就断开了连接。
  • 把 WebSocket 当作唯一的进度通道,没有轮询兜底。
  • 本地什么都不存,一次重启就丢失了用户与在途任务之间的映射关系。
  • 忘了结果是临时的,指望 API 充当永久存储。

合理的推进顺序

在写任何应用代码之前,先用 curl 把一张照片跑通全流程——提交、轮询、下载。然后把同样这四次调用接进后端并做好持久化。WebSocket 放到最后再加,纯粹作为进度条体验的增强,叠加在一个没有它也能正常工作的系统之上。按这个顺序,集成是一天的活;反过来,就是两周的调试。

常见问题

一次请求需要多久?

生成是异步的,在后台完成。请围绕进度状态而不是阻塞调用来设计界面,这样具体耗时对你的架构就不再重要。

必须用 WebSocket 才能调用 API 吗?

不需要。仅用 REST 就能完成全部流程。WebSocket 的存在只是让进度显示更实时,轮询任务接口能拿到同样的信息。

如果同一个请求提交了两次会怎样?

只要幂等键相同,你拿回的就是原任务,不会产生第二次生成,也不会重复计费。

基于 uncloth.app 开发

一个 REST 接口、十一种预设,结果直接回传到你的后端。告诉我们你在做什么产品,我们会发送接入信息。

申请接入

全部指南