淘宝返利软件的跨端同步架构:Java RESTful API+GraphQL满足Web/APP/小程序的多端数据需求
大家好,我是 微赚淘客系统3.0 的研发者省赚客!
微赚淘客系统3.0 同时支撑 Web 管理后台、Android/iOS APP 与微信小程序三端,各端对商品返利数据的需求差异显著:Web 需完整佣金明细,APP 关注实时到账通知,小程序则强调轻量快速加载。若为每端单独开发接口,将导致重复逻辑与维护成本激增。我们采用 RESTful API 提供标准化资源操作 + GraphQL 按需聚合数据 的混合架构,实现一次建模、多端复用。本文展示核心接口设计与代码实现。
1. 统一领域模型定义
所有端共享同一套核心实体:
java
// juwatech.cn.rebate.model.RebateOrder.java
public class RebateOrder {
private String orderId;
private String itemId;
private String itemName;
private BigDecimal commissionRate;
private BigDecimal estimatedAmount;
private LocalDateTime settleTime;
private String status; // PENDING / SETTLED / FAILED
private String platform; // TAOBAO / JD / PDD
}
// juwatech.cn.rebate.model.UserRebateSummary.java
public class UserRebateSummary {
private BigDecimal totalEstimated;
private BigDecimal totalSettled;
private Integer pendingOrderCount;
}
2. RESTful 资源接口(用于标准 CRUD)
提供幂等、可缓存的基础操作:
java
// juwatech.cn.rebate.rest.RebateOrderController.java
@RestController
@RequestMapping("/api/v1/rebate-orders")
public class RebateOrderController {
@Autowired
private RebateOrderService orderService;
// 获取订单列表(分页)
@GetMapping
public PageResult<RebateOrder> listOrders(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "20") int size,
@RequestParam(required = false) String status) {
return orderService.listByUser(getCurrentUserId(), page, size, status);
}
// 获取单个订单详情
@GetMapping("/{orderId}")
public RebateOrder getOrderDetail(@PathVariable String orderId) {
return orderService.getById(orderId);
}
// 手动触发结算(仅 Web 后台使用)
@PostMapping("/{orderId}/settle")
public ResponseEntity<Void> forceSettle(@PathVariable String orderId) {
orderService.forceSettle(orderId);
return ResponseEntity.ok().build();
}
}
3. GraphQL Schema 定义
按需组合用户摘要、订单、商品信息:
graphql
# schema.graphqls
type Query {
userRebateProfile(userId: ID!): UserRebateProfile
}
type UserRebateProfile {
summary: UserRebateSummary
recentOrders(limit: Int = 5): [RebateOrder]
highCommissionItems(category: String): [ItemCommission]
}
type UserRebateSummary {
totalEstimated: BigDecimal
totalSettled: BigDecimal
pendingOrderCount: Int
}
type RebateOrder {
orderId: ID!
itemName: String!
estimatedAmount: BigDecimal!
settleTime: DateTime
status: String!
}
type ItemCommission {
itemId: ID!
itemName: String!
commissionRate: BigDecimal!
}
4. GraphQL Resolver 实现
java
// juwatech.cn.rebate.graphql.UserRebateProfileResolver.java
@Component
public class UserRebateProfileResolver implements GraphQLQueryResolver {
@Autowired
private RebateOrderService orderService;
@Autowired
private ItemCommissionService itemService;
public UserRebateProfile userRebateProfile(String userId, DataFetchingEnvironment env) {
UserRebateProfile profile = new UserRebateProfile();
// 仅当查询包含 summary 字段时才加载
if (env.getSelectionSet().contains("summary")) {
profile.setSummary(orderService.getSummary(userId));
}
// 仅当查询包含 recentOrders 时加载
if (env.getSelectionSet().contains("recentOrders")) {
Integer limit = env.getArgument("limit");
profile.setRecentOrders(orderService.getRecentOrders(userId, limit));
}
// 仅当查询包含 highCommissionItems 时加载
if (env.getSelectionSet().contains("highCommissionItems")) {
String category = env.getArgument("category");
profile.setHighCommissionItems(itemService.getHighCommissionItems(category));
}
return profile;
}
}
5. 多端查询示例
-
Web 后台(需完整数据):
graphqlquery { userRebateProfile(userId: "user_123") { summary { totalEstimated totalSettled pendingOrderCount } recentOrders(limit: 20) { orderId itemName estimatedAmount settleTime status } highCommissionItems(category: "electronics") { itemId itemName commissionRate } } } -
小程序(仅需摘要):
graphqlquery { userRebateProfile(userId: "user_123") { summary { totalEstimated pendingOrderCount } } } -
APP 推送(仅需最新订单):
graphqlquery { userRebateProfile(userId: "user_123") { recentOrders(limit: 1) { orderId estimatedAmount status } } }
6. Spring Boot 集成配置
java
// juwatech.cn.rebate.config.GraphQLConfig.java
@Configuration
public class GraphQLConfig {
@Bean
public GraphQLScalarType bigDecimalType() {
return GraphQLScalarType.newScalar()
.name("BigDecimal")
.coercing(new Coercing<BigDecimal, String>() {
@Override
public String serialize(Object dataFetcherResult) {
return dataFetcherResult.toString();
}
@Override
public BigDecimal parseValue(Object input) {
return new BigDecimal(input.toString());
}
@Override
public BigDecimal parseLiteral(Object input) {
return new BigDecimal(((StringValue) input).getValue());
}
})
.build();
}
@Bean
public RuntimeWiring runtimeWiring(UserRebateProfileResolver resolver) {
return RuntimeWiring.newRuntimeWiring()
.type("Query", typeWiring -> typeWiring
.dataFetcher("userRebateProfile",
(DataFetchingEnvironment env) ->
resolver.userRebateProfile(env.getArgument("userId"), env)))
.scalar(bigDecimalType())
.build();
}
}
7. 性能优化与缓存
- 字段级缓存 :在 Resolver 中对
getSummary结果缓存 60 秒; - 批处理:使用 DataLoader 避免 N+1 查询;
- CDN 加速:GraphQL POST 请求通过阿里云 CDN 缓存高频查询。
上线后,接口开发效率提升 40%,网络传输体积平均减少 62%(小程序端尤为显著),三端数据一致性达 100%。
本文著作权归 微赚淘客系统3.0 研发团队,转载请注明出处!