检查-->
我的模型看起来像这样。
@Document
public class PlanDetails {
@Id
private String id;
private String name;
private Double balance;
private Double internet;
private Date date;
--> //String of id's basically.
private List<String> members;
public PlanDetails(){}
public PlanDetails(String id, String name, Double balance, Double internet, Date date, List<String> members){
this.id = id;
this.name = name;
this.balance = balance;
this.internet = internet;
this.date = date;
this.members = members;
}
public String getId() {
return id;
}
/* Getter setters ommited for brevity */
这是我的处理程序类,用于处理我的功能端点。
package com.startelco.plandetailsapi.handler;
import com.startelco.plandetailsapi.model.PlanDetails;
import com.startelco.plandetailsapi.repository.PlanRepository;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import static org.springframework.http.MediaType.APPLICATION_JSON;
@Component
public class PlanDetailsHandler {
private PlanRepository repository;
public PlanDetailsHandler(PlanRepository repository){
this.repository = repository;
}
//Get All Users
public Mono<ServerResponse> getAllUsers(ServerRequest request){
Flux<PlanDetails> users = repository.findAll();
return ServerResponse.ok()
.contentType(APPLICATION_JSON)
.body(users,PlanDetails.class);
}
--> //Get User by ID
public Mono<ServerResponse> getUserDetails(ServerRequest request){
String id = request.pathVariable("id");
Mono<PlanDetails> userMono = repository.findById(id);
Mono<ServerResponse> notFound = ServerResponse.notFound().build();
return userMono.flatMap(user ->
ServerResponse.ok()
.contentType(APPLICATION_JSON)
.body(BodyInserters.fromObject(user))
.switchIfEmpty(notFound)
);
}
//Create a user
public Mono<ServerResponse> saveUser(ServerRequest request){
Mono<PlanDetails> userMono = request.bodyToMono(PlanDetails.class);
return userMono.flatMap(user ->
ServerResponse.status(HttpStatus.CREATED)
.contentType(APPLICATION_JSON)
.body(repository.save(user),PlanDetails.class)
);
}
//Update user by ID
public Mono<ServerResponse> updateUser(ServerRequest request) {
String id = request.pathVariable("id");
Mono<PlanDetails> existingUserMono = this.repository.findById(id);
Mono<PlanDetails> userMono = request.bodyToMono(PlanDetails.class);
Mono<ServerResponse> notFound = ServerResponse.notFound().build();
return userMono.zipWith(existingUserMono,
(user, existingUser) ->
new PlanDetails(existingUser.getId(), user.getName(), user.getBalance(), user.getInternet(),user.getDate(),user.getMembers())
)
.flatMap(user ->
ServerResponse.ok()
.contentType(APPLICATION_JSON)
.body(repository.save(user), PlanDetails.class)
).switchIfEmpty(notFound);
}
//Delete All Users
public Mono<ServerResponse> deleteAllUsers(ServerRequest request) {
return ServerResponse.ok()
.build(repository.deleteAll());
}
}
问题:通过重用先前编写的功能getMemberDetails
,对getUserDetails.
进行编码的反应性方法是什么?
要求。
所需功能:获取会员详细信息功能。
public Mono<ServerResponse> getMemberDetails(ServerRequest request) {
--> //Pseudocode
String id = request.pathVariable("id");
Mono<PlanDetails> userMono = repository.findById(id);
Mono<ServerResponse> notFound = ServerResponse.notFound().build();
if(userMono.member is not null){
int length = userMono.member.length
Flux<PlanDetails> memberFlux;
for(int i=0;i<length;i++){
Mono<PlanDetails> member = getUserDetails(id=userMono.member[i]);
memberFlux.add(member);
}
}else{
return ServerResponse.ok().build(memberFlux=null or empty array);
}
return ServerResponse.ok().build(memberFlux.flatmap);
}
期望的行为
{
"id": "5b42ecc11cde674475cab39a",
"name": "Alex Svirsky",
"balance": 140,
"internet": 20,
"date": 1531107095659,
"members": [
"5b42ecdd1cde674475cab39b",
"5b42ed421cde674475cab39c",
"5b42ed5d1cde674475cab39d"
]
}
我的路线中的REST调用定义为http://localhost:8080/users/members/5b42ecc11cde674475cab39a
[ {
"id": "5b42ecdd1cde674475cab39b",
"name": "Bob Marley",
"balance": 120,
"internet": 9,
"date": 1531107095559,
"members": null
},
{
"id": "5b42ed421cde674475cab39c",
"name": "Charlie Sheen",
"balance": 10,
"internet": 9,
"date": 1531107095555,
"members": null
},
{
"id": "5b42ed5d1cde674475cab39d",
"name": "Dale Carnegie",
"balance": 100,
"internet": 9,
"date": 1531107055555,
"members": null
}
]
答案 0 :(得分:4)
在我看来,第一种方法没有太多可重复使用的:由于这两种方法都返回格式完整的ServerResponse
,因此您无法撰写原始文档。仅仅是repository.findById()
并带有一些样板,可以将其转换为ok
响应或404
响应...
因此,您实际需要的是在许多对getMemberDetails
的调用之上组成repository.findById
的方法。如果我正确地解释了您的伪代码,您是否希望响应只是原始“用户”下所有“成员”的Flux<PlanDetail>
(忽略有关原始用户的信息)?
您应该能够使用flatMap
来做到这一点:
public Mono<ServerResponse> getMemberDetails(ServerRequest request) {
String id = request.pathVariable("id");
Mono<PlanDetails> userMono = repository.findById(id);
Mono<ServerResponse> notFound = ServerResponse.notFound().build();
return userMono
//transform from user mono to Flux of member details
.flatMap(user -> Flux.fromArray(user.member)) //if `member` is an Iterable use the following instead:
//.flatMapIterable(user -> user.member)
//now we have a Flux of member IDs, go get details
.flatMap(repository::findById)
//this will naturally ignore not found members
//if no member is found or array of IDs is empty, the main sequence is itself empty at this point
.switchIfEmpty(notFound);
}
此方法的唯一警告是,它无法区分“未找到”(未找到原始用户)与“没有内容”(用户没有可以找到的成员)。
答案 1 :(得分:0)
我认为这最终对我有用。很抱歉,我的伪代码不是很清楚。感谢您的回答@Simon Baslé
sidey2-sidey3