ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

山海万灵 HarmonyOS 文化知识实战(13):Mock API 与真实 API 的契约对齐

山海万灵 HarmonyOS 文化知识实战(13):Mock API 与真实 API 的契约对齐 知识应用在接入服务端时最怕的不是某一次请求失败而是同一张页面因数据源不同出现两套字段和两套状态。 HTTP 502 后本地 Mock 回退把页面渲染、数据读取和异常恢复放在同一条可追踪链路上页面只消费稳定模型Repository 负责选择数据源状态层只根据结果刷新。一、先固定页面真正依赖的数据列表、区域、展厅、档案统计和推荐卡片都不应直接绑定某个请求返回。页面需要的是名称、摘要、归属关系、进度和可继续操作的状态这些字段必须在切换数据源前被整理为同一模型。MockShanhaiRepository、HttpShanhaiRepository 与 FallbackShanhaiRepository承担的正是这一层边界因此 UI 不需要为本地数据和网络数据写两套判断。对象页面需要的字段归属神兽条目名称、区域、摘要、发现状态领域模型探索进度已发现、印章、最后位置状态协调层服务结果成功内容或可恢复提示Repository二、契约从接口而不是页面文本开始统一接口让页面的加载顺序保持稳定先得到 Bootstrap再渲染列表与进度发现动作返回新的计数和印章集合而不是让组件猜测请求是否成功。对于设计主题同一接口也是后续键鼠激活命令的唯一入口。interface ShanhaiRepository { loadBootstrap(): PromiseShanhaiBootstrap listBeasts(): PromiseBeastItem[] listRegions(): PromiseRegionItem[] listHalls(): PromiseHallItem[] getOverview(): PromiseProfileOverview discoverBeast(beastId: string): PromiseDiscoveryResult }三、把源选择压缩到 Repository 边界页面层不关心当前返回来自 HTTP 还是本地数据。网络端只负责把响应映射为领域模型本地端提供相同形状的内容回退层只在主数据源不可用时接管。这样保留了网络错误事实也不会让首页因为一次服务端故障失去可阅读内容。class FallbackRepository implements ShanhaiRepository { constructor(private primary: ShanhaiRepository, private backup: ShanhaiRepository) {} async loadBootstrap(): PromiseShanhaiBootstrap { try { return await this.primary.loadBootstrap() } catch (_) { return await this.backup.loadBootstrap() } } }四、状态模型要表达可观察结果HTTP 502 后本地 Mock 回退不能只用一个布尔值表示“正在加载”。页面至少要区分内容、空态、不可用和重试入口输入方案还需要把 hover、focus 与 selected 分开。分离后的状态可以准确告诉读者当前看到的是业务选中、临时悬停还是可激活焦点。type LoadState LOADING | CONTENT | EMPTY | ERROR type InputMode touch | mouse | keyboard interface ViewState { loadState: LoadState selectedId: string focusedId: string hoveredId: string }五、异常路径必须保持可继续操作网络不可用时应用应保留上一次可展示的模型或进入本地内容不把低层错误直接泄漏给页面。设计中的键鼠路径同样如此禁用控件不能继续获得可激活焦点窗口缩放导致目标消失时焦点应回退到所属区域第一个可操作元素。错误提示与恢复命令是模型的一部分。场景风险处理HTTP 请求失败首页没有内容回退到同契约本地数据数据为空详情继续渲染显示空态并保留重试焦点目标卸载键盘操作中断回退到区域首个控件重复发现统计重复累加返回已存在结果六、页面拆分只保留必要的协调Feature 页面负责自己的布局、卡片和交互细节入口页只保留一级导航、选中实体和页面组合AppViewModel 处理 Bootstrap、进度合并、发现动作与推荐上下文。这样的边界既让页面可独立演进也避免为追求文件数量而把一次用户动作拆散到没有唯一入口的位置。async function onActivate(id: string): Promisevoid { if (!this.viewState.focusedId id.length 0) return const result await this.appViewModel.discover(id) this.viewState.selectedId id this.notice result.notice this.refreshProfile(result.discoveredIds, result.passportRegionIds) }七、如何检查这条链路验证时先进入首页确认数据源提示和统计区域已经出现再进入图鉴、探索与馆长页面检查同一实体在不同 Feature 中的名称、区域和进度是否一致对可操作卡片执行一次发现或激活动作再回读统计、提示与当前选中状态。若网络端不可用应确认页面进入可继续阅读的本地模式而不是停在空白等待。八、边界与取舍回退并不把网络失败伪装为服务端成功服务端错误仍然是错误页面只是用同一契约的本地内容维持阅读与探索。页面拆分也不意味着入口页完全没有状态一级导航和跨页回调仍由壳层统一协调。设计方案中的 hover、focus 与键盘激活在实现后还需要在 2in1 窗口完成专项回归。把返回值收敛为页面命令一个动作完成后页面不应根据 HTTP 状态码、字段缺失或输入设备类型分别更新多个局部变量。Repository 先把外部结果转换为领域对象ViewModel 再把领域对象转换为页面命令更新统计、保留当前实体、刷新提示或打开恢复入口。这样同一动作在网络可用、本地回退和未来的键盘激活场景中具有一致的后置状态。这条边界还能降低版本演进的成本。服务端新增字段时映射层可以先提供默认值本地数据仍按旧字段继续工作页面无需为了兼容分支散落条件表达式。对于不应默认的关键字段映射层应返回可读错误并交给状态面板展示而不是构造半完整详情。function applyDiscovery(result: DiscoveryResult): ViewCommand { return { type: result.created ? DISCOVERY_CREATED : DISCOVERY_EXISTS, discoveredIds: result.discoveredIds.slice(), passportRegionIds: result.passportRegionIds.slice(), notice: result.notice, keepSelection: true } } function normalizeEntity(item: ApiBeast): BeastItem { if (!item.id || !item.name || !item.regionId) { throw new Error(实体缺少渲染详情所需的标识字段) } return { id: item.id, name: item.name, alias: item.alias || , regionId: item.regionId, hallId: item.hallId || , summary: item.summary || } }提交前后的稳定性检查检查重点不是页面看起来“有内容”而是同一实体在首页、图鉴、探索和档案中的引用是否一致。切换页面后返回原页面应保留业务 selectedId临时的 hoveredId 与 focusedId 则可按输入模式重新计算。请求失败、快速重复操作和窗口尺寸变化都应走同一套状态回收规则。统计字段必须拥有单一事实来源。发现数量、护照印章和最后探索位置应由同一份进度快照派生动作返回后一次性替换首页、图鉴和档案页只读取该快照不各自计算。这样从详情返回、重新请求内容或重启应用时数字与路线能回到相同业务状态。推荐卡片也要区分无结果、暂不可用和已回退。空数组不能被解释为没有关联内容网络失败也不能伪装为推荐成功状态面板需要给出继续浏览、重新同步或返回上级的明确动作。把这些语义放在模型层Feature 页面就无需复制异常判断。const fallbackRoute { kind: LOCAL, retryable: true } const emptyRoute { kind: EMPTY, retryable: false } const errorRoute { kind: ERROR, retryable: true } const contentRoute { kind: CONTENT, retryable: false }九、验收结论HTTP 502 后本地 Mock 回退的验收重点是模型是否一致、异常是否可恢复、页面边界是否清晰。读者可以从统一接口、状态字段、回退规则和实际页面回读四个角度检查实现每新增一个数据源或输入方式都先接入这些边界再扩展具体页面。参考 HarmonyOS 网络请求指南。
返回列表