Skip to content

Commit

Permalink
Feat: 사용자는 도메인과 연관된 링크 목록을 조회할 수 있다.
Browse files Browse the repository at this point in the history
Feat: 사용자는 도메인과 연관된 링크 목록을 조회할 수 있다.
  • Loading branch information
hseong3243 authored Mar 28, 2024
2 parents 0096dca + 92019f0 commit 683692b
Show file tree
Hide file tree
Showing 16 changed files with 389 additions and 13 deletions.
10 changes: 10 additions & 0 deletions src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,13 @@ operation::domain-controller-test/find-domain[snippets='http-request,path-parame
==== response

operation::domain-controller-test/find-domain[snippets='http-response,response-fields']

=== 도메인 링크 목록 조회

==== request

operation::domain-controller-test/find-domain-links[snippets='http-request,path-parameters,query-parameters']

==== response

operation::domain-controller-test/find-domain-links[snippets='http-response,response-fields']
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package com.seong.shoutlink.domain.domain.controller;

import com.seong.shoutlink.domain.domain.controller.request.FindDomainLinksRequest;
import com.seong.shoutlink.domain.domain.controller.request.FindDomainsRequest;
import com.seong.shoutlink.domain.domain.controller.request.FindRootDomainsRequest;
import com.seong.shoutlink.domain.domain.service.DomainService;
import com.seong.shoutlink.domain.domain.service.request.FindDomainCommand;
import com.seong.shoutlink.domain.domain.service.request.FindDomainLinksCommand;
import com.seong.shoutlink.domain.domain.service.request.FindDomainsCommand;
import com.seong.shoutlink.domain.domain.service.request.FindRootDomainsCommand;
import com.seong.shoutlink.domain.domain.service.response.FindDomainDetailResponse;
import com.seong.shoutlink.domain.domain.service.response.FindDomainLinksResponse;
import com.seong.shoutlink.domain.domain.service.response.FindDomainsResponse;
import com.seong.shoutlink.domain.domain.service.response.FindRootDomainsResponse;
import jakarta.validation.Valid;
Expand Down Expand Up @@ -48,4 +51,13 @@ public ResponseEntity<FindDomainDetailResponse> findDomain(
= domainService.findDomain(new FindDomainCommand(domainId));
return ResponseEntity.ok(response);
}

@GetMapping("/{domainId}/links")
public ResponseEntity<FindDomainLinksResponse> findDomainLinks(
@PathVariable("domainId") Long domainId,
@ModelAttribute @Valid FindDomainLinksRequest request) {
FindDomainLinksResponse response = domainService.findDomainLinks(
new FindDomainLinksCommand(domainId, request.page(), request.size()));
return ResponseEntity.ok(response);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.seong.shoutlink.domain.domain.controller.request;

import jakarta.validation.constraints.Min;
import java.util.Objects;
import org.hibernate.validator.constraints.Range;

public record FindDomainLinksRequest(
@Min(value = 0, message = "페이지는 음수일 수 없습니다.")
Integer page,
@Range(min = 1, max = 100, message = "사이즈는 1 이상 100 이하여야 합니다.")
Integer size) {

public FindDomainLinksRequest(Integer page, Integer size) {
this.page = Objects.isNull(page) ? 0 : page;
this.size = Objects.isNull(size) ? 10 : size;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import com.seong.shoutlink.domain.domain.Domain;
import com.seong.shoutlink.domain.domain.service.DomainRepository;
import com.seong.shoutlink.domain.domain.service.result.DomainLinkPaginationResult;
import com.seong.shoutlink.domain.domain.service.result.DomainLinkResult;
import com.seong.shoutlink.domain.link.repository.LinkJpaRepository;
import java.util.List;
import com.seong.shoutlink.domain.domain.service.result.DomainPaginationResult;
import java.util.Optional;
Expand All @@ -16,6 +19,7 @@ public class DomainRepositoryImpl implements DomainRepository {

private final DomainJpaRepository domainJpaRepository;
private final DomainCacheRepository domainCacheRepository;
private final LinkJpaRepository linkJpaRepository;

@Override
public Optional<Domain> findByRootDomain(String rootDomain) {
Expand Down Expand Up @@ -54,4 +58,15 @@ public Optional<Domain> findById(Long domainId) {
return domainJpaRepository.findById(domainId)
.map(DomainEntity::toDomain);
}

@Override
public DomainLinkPaginationResult findDomainLinks(Domain domain, int page, int size) {
PageRequest pageRequest = PageRequest.of(page, size);
Page<DomainLinkResult> domainLinks
= linkJpaRepository.findDomainLinks(domain.getDomainId(), pageRequest);
return new DomainLinkPaginationResult(
domainLinks.getContent(),
domainLinks.getTotalElements(),
domainLinks.hasNext());
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package com.seong.shoutlink.domain.domain.service;

import com.seong.shoutlink.domain.domain.Domain;
import java.util.List;
import com.seong.shoutlink.domain.domain.service.result.DomainLinkPaginationResult;
import com.seong.shoutlink.domain.domain.service.result.DomainPaginationResult;
import java.util.List;
import java.util.Optional;

public interface DomainRepository {
Expand All @@ -18,4 +19,6 @@ public interface DomainRepository {
DomainPaginationResult findDomains(String keyword, int page, int size);

Optional<Domain> findById(Long domainId);

DomainLinkPaginationResult findDomainLinks(Domain domain, int page, int size);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

import com.seong.shoutlink.domain.domain.Domain;
import com.seong.shoutlink.domain.domain.service.request.FindDomainCommand;
import com.seong.shoutlink.domain.domain.service.request.FindDomainLinksCommand;
import com.seong.shoutlink.domain.domain.service.request.FindDomainsCommand;
import com.seong.shoutlink.domain.domain.service.request.FindRootDomainsCommand;
import com.seong.shoutlink.domain.domain.service.request.UpdateDomainCommand;
import com.seong.shoutlink.domain.domain.service.response.FindDomainDetailResponse;
import com.seong.shoutlink.domain.domain.service.response.FindDomainLinksResponse;
import com.seong.shoutlink.domain.domain.service.response.FindDomainsResponse;
import com.seong.shoutlink.domain.domain.service.response.FindRootDomainsResponse;
import com.seong.shoutlink.domain.domain.service.response.UpdateDomainResponse;
import com.seong.shoutlink.domain.domain.service.result.DomainLinkPaginationResult;
import com.seong.shoutlink.domain.domain.service.result.DomainPaginationResult;
import com.seong.shoutlink.domain.domain.util.DomainExtractor;
import com.seong.shoutlink.domain.exception.ErrorCode;
Expand Down Expand Up @@ -56,8 +59,19 @@ public FindDomainsResponse findDomains(FindDomainsCommand command) {
}

public FindDomainDetailResponse findDomain(FindDomainCommand command) {
Domain domain = domainRepository.findById(command.domainId())
.orElseThrow(() -> new ShoutLinkException("존재하지 않는 도메인입니다.", ErrorCode.NOT_FOUND));
Domain domain = getDomain(command.domainId());
return FindDomainDetailResponse.from(domain);
}

public FindDomainLinksResponse findDomainLinks(FindDomainLinksCommand command) {
Domain domain = getDomain(command.domainId());
DomainLinkPaginationResult result
= domainRepository.findDomainLinks(domain, command.page(), command.size());
return FindDomainLinksResponse.of(result.links(), result.totalElements(), result.hasNext());
}

private Domain getDomain(Long domainId) {
return domainRepository.findById(domainId)
.orElseThrow(() -> new ShoutLinkException("존재하지 않는 도메인입니다.", ErrorCode.NOT_FOUND));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.seong.shoutlink.domain.domain.service.request;

public record FindDomainLinksCommand(Long domainId, int page, int size) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.seong.shoutlink.domain.domain.service.response;

public record FindDomainLinkResponse(Long linkId, String url, long aggregationCount) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.seong.shoutlink.domain.domain.service.response;

import com.seong.shoutlink.domain.domain.service.result.DomainLinkResult;
import java.util.List;

public record FindDomainLinksResponse(
List<FindDomainLinkResponse> links,
long totalElements,
boolean hasNext) {


public static FindDomainLinksResponse of(
List<DomainLinkResult> links,
long totalElements,
boolean hasNext) {
List<FindDomainLinkResponse> content = links.stream()
.map(link -> new FindDomainLinkResponse(
link.linkId(),
link.url(),
link.aggregationCount())
).toList();
return new FindDomainLinksResponse(content, totalElements, hasNext);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.seong.shoutlink.domain.domain.service.result;

import java.util.List;

public record DomainLinkPaginationResult(
List<DomainLinkResult> links,
long totalElements,
boolean hasNext) {


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.seong.shoutlink.domain.domain.service.result;

public record DomainLinkResult(Long linkId, String url, long aggregationCount) {

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
package com.seong.shoutlink.domain.link.repository;

import com.seong.shoutlink.domain.domain.service.result.DomainLinkResult;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface LinkJpaRepository extends JpaRepository<LinkEntity, Long> {

Page<LinkEntity> findAllByLinkBundleId(Long linkBundleId, Pageable pageable);

@Query("select new com.seong.shoutlink.domain.domain.service.result.DomainLinkResult(l.linkId, l.url, count(l.url))"
+ " from LinkEntity l"
+ " where l.domainId = :domainId"
+ " group by l.url"
+ " order by count(l.url) desc")
Page<DomainLinkResult> findDomainLinks(@Param("domainId") Long domainId, Pageable pageable);
}
Loading

0 comments on commit 683692b

Please sign in to comment.