I working on a Quarkus + MongoDB Reactive+ Mutiny application. I have a Person object and Event Object. I am creating a new event for a person. My uri looks like this
POST /person/{personId}/event
I need to first check if the person exists in MongoDB. If the person exists then save event. If person does not exist then create a Error Status and return. I am tried everything but I am stuck and getting error that required return type is Uni but required type is Uni. I tried with transformToUni as well but it did not work. Also tried few other ways like onItemOrFailure() etc. but nothing seems to work.
Here's the full Code.
public class EventResource {
@Inject
EventRepository eventRepository;
@Inject
PersonRepository personRepository;
@POST
@Path("/{person_id}/event")
public Uni<Response> create(Event event, @PathParam("person_id") String personId){
//Check if personId exist.
Uni<Person> uniPerson = personRepository.getPersonById(personId);
//THIS WORKS BUT ON FAILURE IS TREATED WHEN ERROR IS RAISED FOR EeventRepository.craete() and not if person is not found.
/*return uniPerson.onItem().ifNotNull()
.transformToUni(pid -> eventRepository.create(event, pid.getId()))
.onItem().transform(e -> Response.ok().entity(e).build())
.onFailure()
.recoverWithItem(f-> {
AStatus status = createErrorStatus(f.getMessage());
return Response.serverError().entity(status).build();
});
*/
Uni<Response> eventResp = uniPerson.onItem().transform(person -> {
if(person==null)
return Response.serverError().build();
else{
return eventRepository.create(event, person.getId())
.onItem().transform(event1 -> Response.ok(event1).build());
}
});
return eventResp;
}
You can use mutiny ifNull:
@POST
@Path("/{person_id}/event")
public Uni<Response> create(Event event, @PathParam("person_id") String personId){
return personRepository
.getPersonById(personId)
.onItem().ifNotNull().transformToUni(person -> createEvent(event, person))
.onItem().ifNull().continueWith(this::personNotFound)
// This onFailure will catch all the errors
.onFailure()
.recoverWithItem(f-> {
AStatus status = createErrorStatus(f.getMessage());
return Response.serverError().entity(status).build();
});
}
private Uni<Response> createEvent(Event event, Person person) {
return eventRepository
.create(event, person.getId())
.map( e -> Response.ok().entity(e).status(CREATED).build())
}
private Response personNotFound() {
return Response.serverError().build();
}
The error you are seeing is because when the item is not null, you are returning a Uni<Uni<Response>>
. This is one way to fix it:
Uni<Response> eventResp = uniPerson
.chain(person -> {
if (person==null)
return Uni.createFrom().item(Response.serverError().build());
else {
return eventRepository
.create(event, person.getId())
.map(event1 -> Response.ok(event1).build());
}
});
I'm using map
and chain
because they are shorter, but you can replace them with onItem().transform(...)
and onItem().transformToUni(...)
.