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

125 lines
5.3 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.article.ArticleCommandService;
import io.spring.application.article.NewArticleParam;
import io.spring.application.article.UpdateArticleParam;
import io.spring.core.article.Article;
import io.spring.core.article.ArticleRepository;
import io.spring.core.favorite.ArticleFavorite;
import io.spring.core.favorite.ArticleFavoriteRepository;
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.ArticlePayload;
import io.spring.graphql.types.CreateArticleInput;
import io.spring.graphql.types.DeletionStatus;
import io.spring.graphql.types.UpdateArticleInput;
import java.util.Collections;
import org.springframework.beans.factory.annotation.Autowired;
@DgsComponent
public class ArticleMutation {
private ArticleCommandService articleCommandService;
private ArticleFavoriteRepository articleFavoriteRepository;
private ArticleRepository articleRepository;
@Autowired
public ArticleMutation(
ArticleCommandService articleCommandService,
ArticleFavoriteRepository articleFavoriteRepository,
ArticleRepository articleRepository) {
this.articleCommandService = articleCommandService;
this.articleFavoriteRepository = articleFavoriteRepository;
this.articleRepository = articleRepository;
}
@DgsData(parentType = MUTATION.TYPE_NAME, field = MUTATION.CreateArticle)
public DataFetcherResult<ArticlePayload> createArticle(
@InputArgument("input") CreateArticleInput input) {
User user = SecurityUtil.getCurrentUser().orElseThrow(AuthenticationException::new);
NewArticleParam newArticleParam =
NewArticleParam.builder()
.title(input.getTitle())
.description(input.getDescription())
.body(input.getBody())
.tagList(input.getTagList() == null ? Collections.emptyList() : input.getTagList())
.build();
Article article = articleCommandService.createArticle(newArticleParam, user);
return DataFetcherResult.<ArticlePayload>newResult()
.data(ArticlePayload.newBuilder().build())
.localContext(article)
.build();
}
@DgsData(parentType = MUTATION.TYPE_NAME, field = MUTATION.UpdateArticle)
public DataFetcherResult<ArticlePayload> updateArticle(
@InputArgument("slug") String slug, @InputArgument("changes") UpdateArticleInput params) {
Article article =
articleRepository.findBySlug(slug).orElseThrow(ResourceNotFoundException::new);
User user = SecurityUtil.getCurrentUser().orElseThrow(AuthenticationException::new);
if (!AuthorizationService.canWriteArticle(user, article)) {
throw new NoAuthorizationException();
}
article =
articleCommandService.updateArticle(
article,
new UpdateArticleParam(params.getTitle(), params.getBody(), params.getDescription()));
return DataFetcherResult.<ArticlePayload>newResult()
.data(ArticlePayload.newBuilder().build())
.localContext(article)
.build();
}
@DgsData(parentType = MUTATION.TYPE_NAME, field = MUTATION.FavoriteArticle)
public DataFetcherResult<ArticlePayload> favoriteArticle(@InputArgument("slug") String slug) {
User user = SecurityUtil.getCurrentUser().orElseThrow(AuthenticationException::new);
Article article =
articleRepository.findBySlug(slug).orElseThrow(ResourceNotFoundException::new);
ArticleFavorite articleFavorite = new ArticleFavorite(article.getId(), user.getId());
articleFavoriteRepository.save(articleFavorite);
return DataFetcherResult.<ArticlePayload>newResult()
.data(ArticlePayload.newBuilder().build())
.localContext(article)
.build();
}
@DgsData(parentType = MUTATION.TYPE_NAME, field = MUTATION.UnfavoriteArticle)
public DataFetcherResult<ArticlePayload> unfavoriteArticle(@InputArgument("slug") String slug) {
User user = SecurityUtil.getCurrentUser().orElseThrow(AuthenticationException::new);
Article article =
articleRepository.findBySlug(slug).orElseThrow(ResourceNotFoundException::new);
articleFavoriteRepository
.find(article.getId(), user.getId())
.ifPresent(
favorite -> {
articleFavoriteRepository.remove(favorite);
});
return DataFetcherResult.<ArticlePayload>newResult()
.data(ArticlePayload.newBuilder().build())
.localContext(article)
.build();
}
@DgsData(parentType = MUTATION.TYPE_NAME, field = MUTATION.DeleteArticle)
public DeletionStatus deleteArticle(@InputArgument("slug") String slug) {
User user = SecurityUtil.getCurrentUser().orElseThrow(AuthenticationException::new);
Article article =
articleRepository.findBySlug(slug).orElseThrow(ResourceNotFoundException::new);
if (!AuthorizationService.canWriteArticle(user, article)) {
throw new NoAuthorizationException();
}
articleRepository.remove(article);
return DeletionStatus.newBuilder().success(true).build();
}
}