WebFlux RestController parameter handling - spring-webflux

I'm using WebFlux to create a REST controller. My question is, how do I handle request parameters/request body? Can I pass them like the old way and remain reactive?
#PostMapping("/register")
Mono<User> register(#Valid #RequestBody UserRegistrationDto userRegistrationDto) {
return userService.registerUser(userRegistrationDto);
}
Or do I need to read the UserRegistrationDto from org.springframework.web.reactive.function.server.ServerRequest and do the validation manually? Maybe my method should accept Mono<UserRegistrationDto>?

You have a choice, if you prefer the 'old' way of RestControllers then the way you posted is just fine. If you prefer the new way of handlers and routes then you would need a serverRequest.bodyToMono as you stated.

Related

Yii2: How to allow Guzzle POST requests in a controller

I’m trying to make a POST request via Guzzle to a Yii controller but getting a "Bad Request #400". I thought when I don’t use behaviours() the controller is automatically accessible to all kinds of requests, but nope. How I can solve this? What would be best practice for CURL/Guzzle requests in Yii2?
class ImportController extends yii\web\Controller {
public function actionIndex() {
return 'OK';
}
}
You should create a rest controller instance (yii\rest\ActiveController) and implement authentication for it as described here: https://www.yiiframework.com/doc/guide/2.0/en/rest-authentication
That is probably the correct approach to your use case, and you would not have to deal with CSRF.

Calling the same endpoint with multiple requests

I'm in the process of deprecating an old API and want two (or multiple) requests to call the same endpoint. Something like this:
#Get('/request') // call endpoint with this request
#Get('/otherRequest') // or with this request
test() {
// do something
}
Clearly another way to do this would be to create another endpoint and use a service to share the functionality, but I am curious if this is possible as it would make the process easier to implement.
#Get(['/request', '/otherRequest'])
test() {
// do something
}
tip: inspect the TS types of #Get() ^^

Is there a way to dynamically change destination in Spring Cloud Stream Reactive method?

I know that if I implement SC Stream Function in Spring reactive way, I can't send DLQ like traditional imperative way.
To do this, I am trying to manually change the Destination in the MessageHeader so that the message goes to the DLQ Topic.
However, if an error occurs, I want to send a message to the zombie Topic using the onErrorContinue method, but that doesn't work.
Shouldn't I produce it in onErrorContinue?
input.flatMap { sellerDto ->
// do something..
}.onErrorContinue { throwable, source ->
log.error("error occured!! ${throwable.message}")
source as Message<*>
Flux.just(MessageBuilder.withPayload(String(source.payload as ByteArray)).setHeader("spring.cloud.stream.sendto.destination","zombie").build())
}
No, since with reactive function the unit of work is the entire stream (not individual item). I provide more details here.
That said, you can inject StreamBridge which is always available as a bean and use it inside of your filter or any other applicable reactive operator. Basically streamBridge.send("destination", Message)

Api Platform with Swift Mailer

I would know if API Platform is reliable to Swift Mailer. In fact, I woul use Swift Mailer to send a email when a new task has add. It works good when I use my controller, but not working with Postman or Swagger UI.
//mail sending
$message = (new \Swift_Message('New task has done !'))
->setContentType('text/html')
->setFrom("fromAdresse#sample.fr")
->setTo('sample#email.com')
->setBody(
$this->renderView('email/new.html.twig',
['work' => $work]));
$mailer->send($message);
I would use the same thing when users pass by the API UI, it's possible to handle the request ? Because controller and API hasn't the same route.
API : /api/works (POST) to add an element
Controller : work/new (POST) to add an element too
How I can use Swift Mailer on the API platform Request ? Or How I can handle the request with custom controller ?
Thx for advice and answers, I'm beginer with both.
The best way is using an Entity listener (see https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/events.html) - you can detect create/update/delete actions there and do other actions like send e-mails. It is also better to have message logic at one place for all controller/api/other requests :-)
Just be careful to select the right Doctrine event. And read details about modifying entities inside these listeners (i.e. to store "email sent" flag or any other values to other entities. It is not straightforward :-) ).

Why does #RepositoryRestController do not have #ResponseBody annotation like #RestController?

I'm using Spring-data-rest and wondering if there is a reason behind the fact that #RestController also has #ResponseBody but #RepositoryRestController has not.
All controllers in Spring Data REST using that annotation return a ResponseEntity<T> anyway, so that technically #ResponseBody is not needed.
We generally prefer ResponseEntity as return type for two reasons:
In controller methods serving REST requests, you usually want to control details of the response (headers, the status code etc.) for which ResponseEntity is exactly the type for.
Spring MVC detects ResponseEntity and thus we don't the additional annotation.
I'm not sure we can actually change that, as despite the name of the annotation, there could be implementations out there that still use view resolution. If you still think, it's a good idea, feel free to raise a ticket in our JIRA.