问题描述
当前,我正在探索响应式编程并使用Spring Boot构建简单的RESTful服务。我正在使用Json占位符服务(https://jsonplaceholder.typicode.com/)来获取数据。
以下是我的应用程序中使用的特定端点
-
@H_502_5@按ID提取用户:https://jsonplaceholder.typicode.com/users/1
@H_502_5@获取用户的帖子:https://jsonplaceholder.typicode.com/users/1/posts
在我的Spring Boot应用程序中,我正在尝试构建一个接受userId的终结点,并使用用户详细信息和帖子进行回复。我使用json占位符服务的上述端点(/ users / {userId}和/ users / {userId} / posts})来构造我的Api响应。以下是我的Api的示例响应有效负载。
示例响应
{
"id":1,"name":"Leanne Graham","username":"Bret","email":"[email protected]","address":{
"street":"Kulas Light","suite":"Apt. 556","city":"Gwenborough","zipcode":"92998-3874","geo":{
"lat":"-37.3159","lng":"81.1496"
}
},"phone":"1-770-736-8031 x56442","website":"hildegard.org","company":{
"name":"Romaguera-Crona","catchPhrase":"multi-layered client-server neural-net","bs":"harness real-time e-markets"
},"posts":[
{
"userId":1,"id":1,"title":"sunt aut facere repellat provident occaecati excepturi optio reprehenderit","body":"quia et suscipit suscipit recusandae consequuntur expedita et cum reprehenderit molestiae ut ut quas totam nostrum rerum est autem sunt rem eveniet architecto"
}
]
}
问题陈述::在用户服务层中,我试图对JSON占位符服务进行异步WebClient调用,以构建如上所述的汇总响应。首先,我尝试进行呼叫以获取用户信息,然后进行呼叫以获取帖子信息。故意,我想模拟依赖关系(仅在获取用户详细信息调用成功后才进行获取帖子Api调用)。但是,似乎我的webClient链已损坏,我可以看到用户的帖子信息不是响应json的一部分,尽管我的服务正在调用获取帖子的详细信息。
以下是我的服务代码:
UserService
@Service
@Slf4j
public class UserService extends BaseJsonPlaceHolderService implements IUserService {
@Autowired
private IPostService postService;
public UserService(@Autowired WebClient.Builder webClientBuilder) {
super(webClientBuilder);
}
/**
* Fetches user with given id from json place holder service
*
* @param userId
* @return
*/
@Override
public Mono<User> fetchById(Integer userId) {
log.info("Calling json place holder service with User Id : {}",userId);
Mono<User> userMono = webClientBuilder
.baseUrl(jsonPlaceHolderApiBaseUrl)
.build()
.get()
.uri(JsonPlaceHolderResources.USERS.getUri() + "/" + userId) // This will be https://jsonplaceholder.typicode.com/users/{userId}
.retrieve()
.onStatus(HttpStatus::is4xxClientError,clientResponse -> {
log.error("User with Id {} not found in json place holder service",userId);
return Mono.just(new UserNotFoundException("User " + userId + " is not found. Please pass valid user Id. To get all users in the system,use '/users' endpoint"));
})
.onStatus(HttpStatus::is5xxServerError,clientResponse -> {
log.error("Internal service error received from json place holder service for fetch all users call. Here is the message");
return Mono.just(new InternalServiceException("Internal service error occurred while fetching all users from the system"));
})
.bodyToMono(User.class);
return userMono.doOnNext(user -> {
postService
.fetchByUserId(userId)
.subscribe(post -> user.getPosts().add(post));
});
}
}
PostService
@Service
@Slf4j
public class PostService extends BaseJsonPlaceHolderService implements IPostService {
@Autowired
private ICommentService commentService;
public PostService(@Autowired WebClient.Builder webClientBuilder) {
super(webClientBuilder);
}
/**
* Fetches all posts for a given user from json place holder service
* @param userId
* @return
*/
@Override
public Flux<Post> fetchByUserId(Integer userId) {
log.info("Calling json placeholder service to fetch posts for UserId : {}",userId);
Flux<Post> postFlux = webClientBuilder
.baseUrl(jsonPlaceHolderApiBaseUrl)
.build()
.get()
.uri(JsonPlaceHolderResources.USERS.getUri() // This will be https://jsonplaceholder.typicode.com/users/{userId}/posts
+ ApplicationConstants.FORWARD_SLASH.getValue()
+ userId
+ JsonPlaceHolderResources.POSTS.getUri())
.retrieve()
.bodyToFlux(Post.class);
return postFlux;
}
}
UserController
@RequestMapping("/users")
public interface IUserController {
/**
* Fetches user detail for given Id
* @param userId
* @return
*/
@GetMapping("/{userId}")
Publisher<User> fetchById(@PathVariable("userId") Integer userId);
}
UserControllerImpl
@RestController
@Slf4j
@requiredArgsConstructor
public class UserController implements IUserController {
private final IUserService userService;
/**
* Fetches user for given Id
* @param userId
* @return
*/
@Override
public Publisher<User> fetchById(Integer userId) {
log.debug("Received fetchUser request for Id : {}",userId);
return userService.fetchById(userId);
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)