作者:维拉德|Java业务开发入门系列 · 第1篇
假设你刚加入一个团队,接到这样一个需求:
在商品列表里增加一个标签。中台返回的商品字段A等于1时,展示这个标签。标签之间有优先级,由运营在后台配置,服务端排序后下发给客户端。
单看条件判断,几行代码就能写出来。进入实际项目后,新人往往会卡在更早的位置:商品列表是哪个接口返回的?字段A从哪里来?应该改哪个服务?已有标签的结构能不能复用?
我的切入方法是:先找线上已经存在的相似标签,抓包看请求和返回,再找到对应实现,读懂它的出入参和打标逻辑,然后对照新需求接入。
下面就沿着这个顺序,走一遍商品打标的接入过程。文中的字段、地址和数据均为简化的教学示例。
一、先补一点背景:我们在调用什么接口?
在Java业务后端开发中,经常会遇到这样的过程:接收请求,处理业务,调用其他服务获取数据,再返回结果。
入门时,可以先认识两种常见的接入方式:
| 接入方式 | 调用前重点看什么 | 调用时怎样准备参数 |
|---|---|---|
| 直接调用HTTP接口 | 请求地址、请求方法、鉴权、请求头和返回格式 | 按约定构造路径参数、查询参数、请求头或请求体 |
| 通过RPC框架调用远程服务,以Dubbo的Java接口式调用为例 | 服务接口、方法签名、API依赖和服务引用配置 | 按方法签名构造参数或请求对象 |
这里要区分几个概念:HTTP是一种应用层协议;RPC是远程过程调用的方式;Dubbo是提供RPC调用等能力的框架。RPC也可以基于HTTP实现,例如Dubbo的Triple协议基于HTTP/2。HTTP概述、Dubbo概念与架构。
你也可能听过SSE。它基于HTTP,支持服务端持续向客户端推送事件,模型流式输出是其中一种应用场景。本篇先聚焦普通的接口接入,SSE后续再展开。SSE使用说明。
从业务开发的角度,两种调用方式可以先沿用同一条思路:
确认接口约定 → 准备调用条件与参数 → 发起调用 → 处理返回结果。
至于目标地址、服务引用和具体调用代码怎样配置,后续会分别讨论。本篇先弄清楚:需要的数据经过哪些位置,我们应该在哪里接入标签。
二、先抓包,找一个现成标签作为入口
1. 找到相似功能
先在已有商品列表中找一个相似标签。可以优先选择展示位置相同、展示方式接近的标签,后面更容易对照返回结构和处理流程。
记下它出现在哪个页面、哪个商品上,以及页面上显示的文案。这样抓到响应后,才能把数据和页面对应起来。
2. 看清请求和响应
打开抓包工具,操作页面,让带有参考标签的商品出现在列表里。找到相关请求后,先记录接口标识、入参和返回结构。
例如,商品列表请求可能是:
http
POST /api/products/list
Content-Type: application/json
{
"scene": "search",
"page": 1,
"pageSize": 20
}
响应里,某个商品带有已有标签:
json
{
"products": [
{
"productId": "P1001",
"labels": [
{
"code": "LABEL_EXISTING",
"text": "现有标签"
}
]
}
]
}
对照页面,确认你找到的就是目标商品和参考标签。此时我们有了几条可继续追查的线索:列表请求、商品标识、标签字段和标签标识。
3. 沿着接口找到服务端代码
接下来,根据请求里的接口标识,结合项目内的路由或接口映射,找到处理请求的服务和入口。如果网关使用统一入口,还需要继续确认它怎样路由到业务服务。
进入代码后,可以沿着响应对象的labels字段、标签标识LABEL_EXISTING,或者标签组装方法继续查找。标签标识可能来自枚举或配置,具体要结合实现追踪。
读已有逻辑时,先回答下面几个问题:
- 参考标签依赖哪个业务字段?
- 字段来自客户端、服务端已有上下文,还是中台返回?
- 什么条件下生成标签?
- 标签在哪里加入商品响应?
- 优先级从哪里读取,在哪里排序?
抓包能帮助我们观察客户端与服务端之间的请求和响应。内部怎样调用中台、怎样判断命中、怎样读取配置,还需要继续看服务端代码和接口说明。
这一阶段的目标,是把一个已经运行的标签看明白,找到新需求可以接入的位置。
三、把参考实现放回整条请求链路
以客户端发起商品列表请求为例,先看这张请求与返回的时序图:

图中蓝色实线表示业务请求,绿色虚线表示响应返回,紫色箭头表示配置读取。步骤7发生在业务服务内部:根据字段A生成标签,再按运营配置排序。
中台返回商品数据后,业务服务完成标签判断、读取运营配置、排序和响应组装,再经网关返回客户端。客户端根据约定结构展示标签。
实际项目可能还有其他服务层,可以沿具体调用继续展开。每一段使用HTTP还是RPC,也要以项目实现为准。
在这条链路中,可以先按下面的分工理解需求:
| 参与方 | 在本例中负责什么 |
|---|---|
| 客户端 | 发起列表请求,按约定结构和顺序展示标签 |
| 网关 | 将请求路由到对应业务服务 |
| 业务服务 | 调用中台,判断标签是否命中,按配置排序并组装返回数据 |
| 中台 | 按接口约定返回商品字段A |
| 运营配置后台 | 提供标签优先级的维护入口 |
服务端读取运营配置,可以复用项目已有的存储、缓存和刷新机制。这里的"读取配置"表示业务依赖,不要求每次商品请求都访问一次运营后台。
四、对接中台:字段A怎么返回,入参要不要增加?
找到已有中台调用后,先确认当前接口是否已经返回字段A。如果已经支持,就继续确认它的含义、类型和所在位置。
如果没有,需要和对应负责人明确接口变更。沟通时可以带着具体需求问:
我在接商品列表标签,规则是商品字段A为1时命中。当前列表接口是否支持返回A?哪些场景需要额外入参?如果需要增加参数,希望一起确认类型、默认行为和返回位置。
这里尤其要看清参数来源。
例如,中台需要一个场景参数,才能决定怎样返回A。那么这个参数可能已经存在于客户端请求里,也可能可以从服务端上下文得到。只有确实需要客户端提供新信息时,才需要同步调整客户端入参。
对接完成后,应当能够说清楚三件事:
- 调用中台需要传什么,参数从哪里来。
- 中台把A返回在哪个位置,类型和含义是什么。
- A属于哪个商品条目,服务端怎样保持商品与字段的对应关系。
商品列表里有多个商品时,这个对应关系很重要。字段放到了错误的条目上,即使判断条件写对,页面展示也会出错。
五、把中台字段转换成客户端标签
假设本例的A是整数,中台返回的某个商品如下:
json
{
"productId": "P1001",
"A": 1
}
服务端拿到这个商品后,根据A == 1生成标签,再把标签放进对应商品的响应里:
json
{
"productId": "P1001",
"labels": [
{
"code": "LABEL_A",
"text": "示例标签"
}
]
}
这是一个简化协议。实际接入时,先看客户端已有标签结构,确认标识、文案和展示字段怎样约定。已有结构能满足需求时,沿用现有约定;新增样式或字段时,再和客户端共同确认。
除了命中条件,还要明确没有命中时怎样返回。本例约定:A不为1或字段缺失时,不生成LABEL_A;没有任何标签时,labels返回空数组。
中台调用失败属于另一类情况,应按服务已有的异常处理约定处理,不能直接把它解释成"商品没有命中标签"。
至此,链路中的关键转换已经清楚:
中台返回字段A → 业务服务判断命中 → 生成标签对象 → 放入对应商品的响应 → 客户端展示。
六、优先级由运营配置,服务端排序后下发
只有一个标签时,顺序问题不明显。一个商品同时命中多个标签后,就需要明确展示顺序。
本例的职责约定是:运营在配置后台设置优先级,服务端读取配置并排序,然后按顺序下发标签列表,客户端按约定展示。
用标签标识关联配置,例如:
| 标签标识 | 配置优先级 |
|---|---|
| LABEL_A | 10 |
| LABEL_EXISTING | 20 |
本例约定数值越小越靠前。如果两个标签同时命中,服务端就把LABEL_A排在LABEL_EXISTING前面。
处理顺序可以保持清楚:
- 根据商品数据收集命中的标签。
- 为标签关联配置中的优先级。
- 排序;优先级相同时,按约定的固定规则确定次序,例如按标签标识排序。
- 如果有展示数量限制,排序后再截取。
- 组装客户端需要的标签结构并下发。
优先级的数值方向、缺少配置时的行为、同优先级的处理,以及最多展示几个标签,都要形成明确约定。接入已有项目时,先查看这些规则是否已经存在。
七、先把明确需求做好,再观察共性和抽象
新人刚接需求时,很难预见所有后续变化。可以从一个具体规则开始,把链路接通,再随着标签增加观察共性。
| 阶段 | 重点完成什么 |
|---|---|
| 一个简单标签 | 用清楚、集中的条件判断生成标签,接入现有返回结构 |
| 多个标签 | 保留各自命中条件,集中处理共同的配置读取、排序和响应组装 |
| 需求持续变化 | 根据实际变化频率,决定哪些内容需要开放配置、哪些处理需要进一步抽象 |
"先简单实现"也要满足本期明确要求。比如,本期已经要求运营调整优先级,第一版就要接入配置;单个标签的命中条件仍可以先写成简单判断。
等接入第二个、第三个标签后,再看看哪些代码反复出现:标签标识和展示结构、候选标签收集、配置读取、排序和组装,都可能有共性。把已经重复的部分集中起来,后续再根据需求演进。
这样做时,新人每一步都有具体问题可以解决,也更容易理解抽象后的结构为什么存在。
八、沿着一条请求,把结果对应起来
最后,把这次需求从头连起来看:
- 请求所需的场景参数,是否按约定传到了中台?
- 中台是否在正确的商品条目上返回A?
- 服务端是否根据A生成了标签?
- 返回的标签顺序,是否符合运营配置?
- 客户端是否在对应商品的位置,按约定结构展示?
回头看这次接入,起点是一个已经存在的标签:先观察页面,抓包找到请求,再读懂对应代码。沿着这个入口,我们才逐步明确了中台字段、服务端判断、运营配置和客户端展示之间的关系。
如果你第一次接到类似需求,可以先完成这件小事:找一个相似功能,把它的请求、返回和处理逻辑对应起来。 有了这个参照,再逐项确认新需求带来的变化。
后续我会分别展开HTTP接口和Dubbo RPC服务的具体调用流程,从参数准备开始,讲到返回结果和常见问题的处理。