/** * */ package com.spring.webflux.demo.controller; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DuplicateKeyException; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import com.spring.webflux.demo.exception.TweetNotFoundException; import com.spring.webflux.demo.model.Tweet; import com.spring.webflux.demo.payload.ErrorResponse; import com.spring.webflux.demo.repository.TweetRepository; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; /** * @author vrajesh * */ @RestController public class TweetController { @Autowired private TweetRepository tweetRepository; /** * Method to return all the tweets * * @return */ @GetMapping("/myTweets") public Flux<Tweet> getAllMyTweets() { return tweetRepository.findAll(); } /** * Method to create a new Tweet * * @param myTweet * @return */ @PostMapping("/createTweet") public Mono<Tweet> createTweet(@Valid @RequestBody Tweet myTweet) { return tweetRepository.save(myTweet); } /** * Method to retrieve tweet by tweetId * * @param tweetId * @return */ @GetMapping("/myTweets/{tweetId}") public Mono<ResponseEntity<Tweet>> getTweetById(@PathVariable(value = "tweetId") String tweetId) { return tweetRepository.findById(tweetId).map(savedTweet -> ResponseEntity.ok(savedTweet)) .defaultIfEmpty(ResponseEntity.notFound().build()); } /** * Method to update Tweet by tweetId * * @param tweetId * @param tweet * @return */ @PutMapping("/myTweets/{tweetId}") public Mono<ResponseEntity<Tweet>> updateTweet(@PathVariable(value = "tweetId") String tweetId, @Valid @RequestBody Tweet tweet) { return tweetRepository.findById(tweetId).flatMap(existingTweet -> { existingTweet.setText(tweet.getText()); return tweetRepository.save(existingTweet); }).map(updateTweet -> new ResponseEntity<>(updateTweet, HttpStatus.OK)) .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND)); } /** * Method to delete Tweet by tweetId * * @param tweetId * @return */ @DeleteMapping("/myTweets/{tweetId}") public Mono<ResponseEntity<Void>> deleteTweet(@PathVariable(value = "tweetId") String tweetId) { return tweetRepository.findById(tweetId) .flatMap(existingTweet -> tweetRepository.delete(existingTweet) .then(Mono.just(new ResponseEntity<Void>(HttpStatus.OK)))) .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND)); } /** * Tweets are Sent to the client as Server Sent Events * * @return */ @GetMapping(value = "/stream/tweets", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<Tweet> streamAllTweets() { return tweetRepository.findAll(); } /** * Exception Handling Examples (These can be put into a @ControllerAdvice to * handle exceptions globally) * * @param ex * @return */ @SuppressWarnings("rawtypes") @ExceptionHandler(DuplicateKeyException.class) public ResponseEntity handleDuplicateKeyException(DuplicateKeyException ex) { return ResponseEntity.status(HttpStatus.CONFLICT) .body(new ErrorResponse("A Tweet with the same text already exists")); } /** * Method to handle tweet not found exception * * @param ex * @return */ @SuppressWarnings("rawtypes") @ExceptionHandler(TweetNotFoundException.class) public ResponseEntity handleTweetNotFoundException(TweetNotFoundException ex) { return ResponseEntity.notFound().build(); } }