Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4주차 과제/권채연] 특정 문자열을 포함하는 shorturl 전체 조회 & Origin Url 수정하기 api 구현 #20

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.example.urlshortener.common.dto.Response;
import com.example.urlshortener.domain.url.controller.request.CreateShortUrlRequest;
import com.example.urlshortener.domain.url.controller.request.UpdateUrlRequest;
import com.example.urlshortener.domain.url.controller.response.ShortUrlResponse;
import com.example.urlshortener.domain.url.dto.ShortenedUrlDto;
import com.example.urlshortener.domain.url.service.UrlService;
Expand All @@ -10,10 +11,13 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.view.RedirectView;

import java.util.List;

@RequiredArgsConstructor
@RestController
@RequestMapping("/short-links")
Expand All @@ -23,11 +27,11 @@ public class UrlController {
private final UrlService urlService;

@Operation(
summary = "URL 단축하기",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "INTERNAL_SERVER_ERROR")
}
summary = "URL 단축하기",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "INTERNAL_SERVER_ERROR")
}
)
@PostMapping
public Response<ShortUrlResponse> createShortUrl(@Valid @RequestBody CreateShortUrlRequest request) {
Expand All @@ -36,12 +40,12 @@ public Response<ShortUrlResponse> createShortUrl(@Valid @RequestBody CreateShort
}

@Operation(
summary = "단축 URL 조회하기",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "URL_NOT_FOUND"),
@ApiResponse(responseCode = "500", description = "INTERNAL_SERVER_ERROR")
}
summary = "단축 URL 조회하기",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "URL_NOT_FOUND"),
@ApiResponse(responseCode = "500", description = "INTERNAL_SERVER_ERROR")
}
)
@GetMapping("/{short_id}")
public Response<ShortUrlResponse> getShortUrl(@NotBlank @PathVariable("short_id") String shortId) {
Expand All @@ -50,11 +54,11 @@ public Response<ShortUrlResponse> getShortUrl(@NotBlank @PathVariable("short_id"
}

@Operation(
summary = "Short URL 리디렉션",
responses = {
@ApiResponse(responseCode = "302", description = "FOUND"),
@ApiResponse(responseCode = "500", description = "INTERNAL_SERVER_ERROR")
}
summary = "Short URL 리디렉션",
responses = {
@ApiResponse(responseCode = "302", description = "FOUND"),
@ApiResponse(responseCode = "500", description = "INTERNAL_SERVER_ERROR")
}
)
@GetMapping("/r/{short_id}")
public RedirectView redirectShortUrl(@NotBlank @PathVariable("short_id") String shortId) {
Expand All @@ -63,4 +67,46 @@ public RedirectView redirectShortUrl(@NotBlank @PathVariable("short_id") String
redirectView.setUrl(originUrl);
return redirectView;
}

@Operation(
summary = "Data JPA로 URL 조회하기",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "INTERNAL_SERVER_ERROR")
}
)
@GetMapping("/list/jpa")
public Response<List<ShortenedUrlDto>> getAllShortUrlContainingInquiryByJPA(@NotBlank @RequestParam("inquiry") String inquiry) {
List<ShortenedUrlDto> shortenedUrls = urlService.getAllShortUrlContainingInquiryByJPA(inquiry);

return Response.data(shortenedUrls);
}

@Operation(
summary = "QueryDSL로 URL 조회하기",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "INTERNAL_SERVER_ERROR")
}
)
@GetMapping("/list/query-dsl")
public Response<List<ShortenedUrlDto>> getAllShortUrlContainingInquiryByQueryDSL(@NotBlank @RequestParam("inquiry") String inquiry) {
List<ShortenedUrlDto> shortenedUrls = urlService.getAllShortUrlContainingInquiryByQueryDSL(inquiry);

return Response.data(shortenedUrls);
}

@Operation(
summary = "Origin URL 수정하기",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "URL_NOT_FOUND"),
@ApiResponse(responseCode = "500", description = "INTERNAL_SERVER_ERROR")
}
)
@PatchMapping("/{short_id}")
public Response<ShortUrlResponse> updateOriginUrl(@NotNull @PathVariable("short_id") Long id, @RequestBody UpdateUrlRequest request) {
ShortenedUrlDto shortenedUrl = urlService.updateOriginUrl(id, request);
return Response.data(ShortUrlResponse.from(shortenedUrl));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.example.urlshortener.domain.url.controller.request;

import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class UpdateUrlRequest {
@NotBlank
private String newOriginUrl;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.example.urlshortener.domain.url.repository;

import com.example.urlshortener.domain.url.entity.ShortenedUrl;

import java.util.List;

public interface ShortenedUrlCustomRepository {
List<ShortenedUrl> getAllShortUrlContainingInquiryByQueryDSL(String inquiry);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.example.urlshortener.domain.url.repository;

import com.example.urlshortener.domain.url.entity.QShortenedUrl;
import com.example.urlshortener.domain.url.entity.ShortenedUrl;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public class ShortenedUrlCustomRepositoryImpl implements ShortenedUrlCustomRepository {
private final JPAQueryFactory jpaQueryFactory;

public ShortenedUrlCustomRepositoryImpl(JPAQueryFactory jpaQueryFactory) {
this.jpaQueryFactory = jpaQueryFactory;
}

@Override
public List<ShortenedUrl> getAllShortUrlContainingInquiryByQueryDSL(String inquiry) {
QShortenedUrl shortenedUrl = QShortenedUrl.shortenedUrl;

return jpaQueryFactory
.selectFrom(shortenedUrl)
.where(shortenedUrl.originUrl.contains(inquiry))
.fetch();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface ShortenedUrlRepository extends JpaRepository<ShortenedUrl, Long> {
public interface ShortenedUrlRepository extends JpaRepository<ShortenedUrl, Long>, ShortenedUrlCustomRepository {

Optional<ShortenedUrl> findByOriginUrl(String longUrl);

Expand All @@ -36,4 +37,6 @@ public interface ShortenedUrlRepository extends JpaRepository<ShortenedUrl, Long
int updateOriginUrlByShortUrl(@Param("originUrl") String originUrl, @Param("shortUrl") String shortUrl);

Iterable<ShortUrlOnly> findShortenedUrlByOriginUrl(String originUrl);

List<ShortenedUrl> findByOriginUrlContaining(String inquiry);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.example.urlshortener.domain.url.service;

import com.example.urlshortener.common.utils.RandomStringUtil;
import com.example.urlshortener.domain.url.controller.request.UpdateUrlRequest;
import com.example.urlshortener.domain.url.dto.ShortenedUrlDto;
import com.example.urlshortener.domain.url.entity.ShortenedUrl;
import com.example.urlshortener.domain.url.exception.UrlNotFoundException;
Expand All @@ -10,6 +11,8 @@
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
Expand All @@ -34,15 +37,44 @@ public ShortenedUrlDto createShortUrl(String url) {

public ShortenedUrlDto getShortUrl(String shortId) {
ShortenedUrl shortenedUrl = shortenedUrlRepository.findByShortUrl(shortId)
.orElseThrow(UrlNotFoundException::new);
.orElseThrow(UrlNotFoundException::new);

return new ShortenedUrlDto(shortenedUrl.getId(), shortenedUrl.getShortUrl(), shortenedUrl.getOriginUrl(), shortenedUrl.getCreatedAt());
}

public String getOriginUrl(String shortId) {
ShortenedUrl shortenedUrl = shortenedUrlRepository.findByShortUrl(shortId)
.orElseThrow(UrlNotFoundException::new);
.orElseThrow(UrlNotFoundException::new);

return shortenedUrl.getOriginUrl();
}

public List<ShortenedUrlDto> getAllShortUrlContainingInquiryByJPA(String inquiry) {
List<ShortenedUrlDto> shortenedUrls = shortenedUrlRepository.findByOriginUrlContaining(inquiry)
.stream().map(ShortenedUrlDto::from).collect(Collectors.toList());

return shortenedUrls;
}

public List<ShortenedUrlDto> getAllShortUrlContainingInquiryByQueryDSL(String inquiry) {
List<ShortenedUrlDto> shortenedUrls = shortenedUrlRepository.getAllShortUrlContainingInquiryByQueryDSL(inquiry)
.stream().map(ShortenedUrlDto::from).collect(Collectors.toList());

return shortenedUrls;
}

public ShortenedUrlDto updateOriginUrl(Long id, UpdateUrlRequest request) {
ShortenedUrl url = shortenedUrlRepository.findById(id)
.orElseThrow(UrlNotFoundException::new);

// originUrl에 바뀌었으니 shortUrl도 새롭게 만들어줌
String newShortUrl = RandomStringUtil.generateRandomString(8);

url.setOriginUrl(request.getNewOriginUrl());
url.setShortUrl(newShortUrl);

shortenedUrlRepository.save(url);

return ShortenedUrlDto.from(url);
}
}