"Add" 似乎在 WebFlux 中工作,但似乎必须有一个 "more accepted way"
"Add" appears to be working in WebFlux, but seems like there must be a "more accepted way"
WebFlux、反应式和处理程序的新手。
我能够从 ServerRequest 获取 Mono<> 并处理包含的 POJO 以将新元组添加到数据库。但是,似乎应该有一种 "better" 或 "more accepted" 的方式来编写这段代码。
任何使用 AccountRequestHandler 中的代码的 help/input 都将不胜感激,尤其是对建议更改背后的基本原理的解释。
路由器实现(精简到只有 "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 的代码是我所关注的。似乎 "clunky",特别是因为 AccountService.addAccount() returns 完成后是一个 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();
}
}
感谢所有帮助提高这种编程风格的人....
首先,您有 2 个 addAccount,这可能有点令人困惑。
其次,"repository"你也在写什么?如果它是一个 sql 存储库,你需要将它正确地包装在一个 Mono.fromCallable()
中,否则它会阻塞 Reactive
线程池,你的性能可能会很差。
是的,还有其他处理方法。很多人倾向于在 flatmap
或 map
中做事,并且肯定在这里做事是完全可能的,但是对于 语义 我会说不太好。
map
和 flatmap
通常用于对单声道的内部值执行某种计算,然后 return 相同的或新的值和/或在内部输入单声道。
我会这样重写。
return 此处无效:
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
方法可用于消费和处理事物 "side effects"。比如doOnSuccess
、doOnError
、doOnCancel
等等等等
您还有 then
和 thenReturn
,它们只会 return 您放入其中的任何内容。 Then
returns 无论你输入什么 Mono
。 thenReturn
将您放入其中的任何值都包装到 Mono
中并 returns 它。
WebFlux、反应式和处理程序的新手。
我能够从 ServerRequest 获取 Mono<> 并处理包含的 POJO 以将新元组添加到数据库。但是,似乎应该有一种 "better" 或 "more accepted" 的方式来编写这段代码。
任何使用 AccountRequestHandler 中的代码的 help/input 都将不胜感激,尤其是对建议更改背后的基本原理的解释。
路由器实现(精简到只有 "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 的代码是我所关注的。似乎 "clunky",特别是因为 AccountService.addAccount() returns 完成后是一个 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();
}
}
感谢所有帮助提高这种编程风格的人....
首先,您有 2 个 addAccount,这可能有点令人困惑。
其次,"repository"你也在写什么?如果它是一个 sql 存储库,你需要将它正确地包装在一个 Mono.fromCallable()
中,否则它会阻塞 Reactive
线程池,你的性能可能会很差。
是的,还有其他处理方法。很多人倾向于在 flatmap
或 map
中做事,并且肯定在这里做事是完全可能的,但是对于 语义 我会说不太好。
map
和 flatmap
通常用于对单声道的内部值执行某种计算,然后 return 相同的或新的值和/或在内部输入单声道。
我会这样重写。
return 此处无效:
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
方法可用于消费和处理事物 "side effects"。比如doOnSuccess
、doOnError
、doOnCancel
等等等等
您还有 then
和 thenReturn
,它们只会 return 您放入其中的任何内容。 Then
returns 无论你输入什么 Mono
。 thenReturn
将您放入其中的任何值都包装到 Mono
中并 returns 它。