package io.spring.graphql.users; import com.netflix.graphql.dgs.DgsComponent; import com.netflix.graphql.dgs.DgsData; import com.netflix.graphql.dgs.InputArgument; import graphql.execution.DataFetcherResult; import io.spring.api.exception.NoAuthorizationException; import io.spring.api.exception.ResourceNotFoundException; import io.spring.application.CommentQueryService; import io.spring.application.data.CommentData; import io.spring.core.article.Article; import io.spring.core.article.ArticleRepository; import io.spring.core.comment.Comment; import io.spring.core.comment.CommentRepository; import io.spring.core.service.AuthorizationService; import io.spring.core.user.User; import io.spring.graphql.AuthenticationException; import io.spring.graphql.DgsConstants.MUTATION; import io.spring.graphql.types.CommentPayload; import io.spring.graphql.types.DeletionStatus; import org.springframework.beans.factory.annotation.Autowired; @DgsComponent public class CommentMutation { private ArticleRepository articleRepository; private CommentRepository commentRepository; private CommentQueryService commentQueryService; @Autowired public CommentMutation( ArticleRepository articleRepository, CommentRepository commentRepository, CommentQueryService commentQueryService) { this.articleRepository = articleRepository; this.commentRepository = commentRepository; this.commentQueryService = commentQueryService; } @DgsData(parentType = MUTATION.TYPE_NAME, field = MUTATION.AddComment) public DataFetcherResult createComment( @InputArgument("slug") String slug, @InputArgument("body") String body) { User user = SecurityUtil.getCurrentUser().orElseThrow(AuthenticationException::new); Article article = articleRepository.findBySlug(slug).orElseThrow(ResourceNotFoundException::new); Comment comment = new Comment(body, user.getId(), article.getId()); commentRepository.save(comment); CommentData commentData = commentQueryService .findById(comment.getId(), user) .orElseThrow(ResourceNotFoundException::new); return DataFetcherResult.newResult() .localContext(commentData) .data(CommentPayload.newBuilder().build()) .build(); } @DgsData(parentType = MUTATION.TYPE_NAME, field = MUTATION.DeleteComment) public DeletionStatus removeComment( @InputArgument("slug") String slug, @InputArgument("id") String commentId) { User user = SecurityUtil.getCurrentUser().orElseThrow(AuthenticationException::new); Article article = articleRepository.findBySlug(slug).orElseThrow(ResourceNotFoundException::new); return commentRepository .findById(article.getId(), commentId) .map( comment -> { if (!AuthorizationService.canWriteComment(user, article, comment)) { throw new NoAuthorizationException(); } commentRepository.remove(comment); return DeletionStatus.newBuilder().success(true).build(); }) .orElseThrow(ResourceNotFoundException::new); } }