spring-boot-realworld-examp.../src/main/java/io/spring/graphql/users/CommentMutation.java
2021-03-19 15:24:10 +08:00

78 lines
3.1 KiB
Java

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<CommentPayload> 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.<CommentPayload>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);
}
}