WebFlux,响应式和处理程序的新手。
我能够从ServerRequest中获取Mono <>并处理所包含的POJO以向数据库添加新的元组。但是,似乎应该有一种“更好”或“被更多接受”的方式来编写此代码。
任何在 AccountRequestHandler 中使用代码的帮助/输入都将受到赞赏,尤其是在解释建议更改的基本原理方面。
路由器实现(简化为“ POST”)...
@Configuration
public class AccountRequestRouter {
@Bean
public RouterFunction<ServerResponse> route(AccountRequestHandler requestHandler) {
return nest(path("/v2"),
nest(accept(APPLICATION_JSON),
.andRoute(RequestPredicates.POST("/accounts"), requestHandler::addAccount)
));
}
}
处理程序实现... 我重点关注的是我实际执行添加操作,然后分别创建 ServerResponse 的代码。似乎“笨拙”,尤其是因为 AccountService.addAccount()在完成时返回Mono。
@Component
public class AccountRequestHandler {
@Autowired
private mil.navy.ccop.service.accounts.account.AccountService accountService;
public Mono<ServerResponse> addAccount(ServerRequest request) {
return request.bodyToMono(Account.class).flatMap(account -> {
accountService.addAccount(account);
return ServerResponse.ok().build();
})
.switchIfEmpty(ServerResponse.badRequest()
.contentType(APPLICATION_JSON)
.build(Mono.empty()));
}
}
AccountService实现(再次精简)...
@Service
class AccountService {
@Autowired
private AccountRepository accounts;
public AccountService() {
}
public Mono<Void> addAccount(Account account) {
Account proxy;
// make sure that accountId is set to support auto-generation of synthetic key value
proxy = new Account(-1, account.getShortName(), account.getLongName(), account.getDescription());
accounts.save(proxy);
return Mono.empty();
}
}
感谢所有帮助,以增强这种编程风格。...
答案 0 :(得分:0)
首先,您有2个addAccount,这可能有点令人困惑。
第二,您也在写什么样的“存储库”?如果它是一个SQL存储库,则需要将其正确包装在Mono.fromCallable()
中,否则它将阻塞Reactive
线程池,并且您的性能可能会很差。
是的,还有其他处理方式。很多人倾向于在flatmap
或map
中做事,并且确定完全有可能在这里做事,但是对于语义学,我会说这不太好
map
和flatmap
通常用于对Mono的内部值执行某种计算,然后返回相同或新的值或在Mono内部键入。
我会这样重写。
在此处返回空白:
public void addAccount(Account account) {
Account proxy;
// make sure that accountId is set to support auto-generation of synthetic key value
proxy = new Account(-1, account.getShortName(), account.getLongName(), account.getDescription());
accounts.save(proxy);
}
在这里:
public Mono<ServerResponse> addAccount(ServerRequest request) {
return request.bodyToMono(Account.class)
.doOnSuccess(account -> {
accountService.addAccount(account);
}).then(ServerResponse.ok().build())
.switchIfEmpty(ServerResponse.badRequest()
.contentType(APPLICATION_JSON)
.build());
}
有许多不同的doOn
方法被用于消耗和对事物产生“副作用”。像doOnSuccess
,doOnError
,doOnCancel
等,等等。
您还拥有then
和thenReturn
,它们将只返回您放入的内容。 Then
返回您放入的任何Mono
。 thenReturn
会将您输入的任何值包装到Mono
中并返回它。