-
Notifications
You must be signed in to change notification settings - Fork 3
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
feat: 반려동물 정보 등록 API 기능 #257
Changes from all commits
ff83c85
aa4072b
d1ccb97
80139e7
cb86b42
1127374
6447189
8559c7a
e298d5c
5ee975f
924db09
f2df4c9
5d674bd
a32c98f
c62cc33
cc3a41a
d5a1dee
86375ed
31f958d
56a09f0
0d1ce09
540b633
51786f3
d0fcc0f
c30e3d8
52da151
9993ea4
f9f790a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package zipgo.common.config; | ||
|
||
import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||
import org.springframework.context.annotation.Configuration; | ||
import zipgo.auth.infra.kakao.config.KakaoCredentials; | ||
|
||
@Configuration | ||
@EnableConfigurationProperties({ | ||
KakaoCredentials.class, | ||
JwtCredentials.class, | ||
AwsS3Credentials.class | ||
}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍🏻 |
||
public class AdditionalConfiguration { | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package zipgo.common.config; | ||
|
||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.boot.context.properties.ConfigurationProperties; | ||
|
||
@Getter | ||
@RequiredArgsConstructor | ||
@ConfigurationProperties(prefix = "cloud.aws.s3") | ||
public class AwsS3Credentials { | ||
|
||
private final String bucket; | ||
private final String zipgoDirectoryName; | ||
private final String petImageDirectory; | ||
private final String imageUrl; | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package zipgo.common.config; | ||
|
||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider; | ||
import software.amazon.awssdk.services.s3.S3Client; | ||
|
||
import static software.amazon.awssdk.regions.Region.AP_NORTHEAST_2; | ||
|
||
@Configuration | ||
public class S3Config { | ||
|
||
@Bean | ||
public S3Client s3Client() { | ||
return S3Client.builder() | ||
.credentialsProvider(ProfileCredentialsProvider.create()) | ||
.region(AP_NORTHEAST_2) | ||
.build(); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package zipgo.image.application; | ||
|
||
import java.util.UUID; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.web.multipart.MultipartFile; | ||
import zipgo.pet.application.ImageClient; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class ImageService { | ||
|
||
private final ImageClient imageClient; | ||
|
||
public String save(MultipartFile image) { | ||
UUID uuid = UUID.randomUUID(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 나중에는 사진 용도가 다양해질텐데, 그 사진들을 어떻게 분류하고 관리할지 고민해볼 수 있겠어요!! (함께) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 맞아요!! 일단 사진이 사용되는 곳이 여기 하나라서 일단 이렇게 만들었어요 🫠 |
||
return imageClient.upload(uuid.toString() ,image); | ||
iamjooon2 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package zipgo.image.infrastructure.aws.s3; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.multipart.MultipartFile; | ||
import zipgo.common.config.AwsS3Credentials; | ||
import zipgo.pet.application.ImageClient; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class S3PetImageClient implements ImageClient { | ||
|
||
private final AwsS3Credentials awsS3Credentials; | ||
private final S3Uploader s3Uploader; | ||
|
||
@Override | ||
public String upload(String name, MultipartFile file) { | ||
String bucket = awsS3Credentials.getBucket(); | ||
String zipgoDirectoryName = awsS3Credentials.getZipgoDirectoryName(); | ||
String petImageDirectory = awsS3Credentials.getPetImageDirectory(); | ||
String key = zipgoDirectoryName + petImageDirectory + name; | ||
s3Uploader.upload(bucket, key, file); | ||
return awsS3Credentials.getImageUrl() + petImageDirectory + name; | ||
iamjooon2 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package zipgo.image.infrastructure.aws.s3; | ||
|
||
import java.io.IOException; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.multipart.MultipartFile; | ||
import software.amazon.awssdk.core.sync.RequestBody; | ||
import software.amazon.awssdk.services.s3.S3Client; | ||
import software.amazon.awssdk.services.s3.model.PutObjectRequest; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class S3Uploader { | ||
|
||
private final S3Client s3Client; | ||
|
||
public void upload(String bucket, String key, MultipartFile file) { | ||
PutObjectRequest objectRequest = PutObjectRequest.builder() | ||
.bucket(bucket) | ||
.key(key) | ||
.contentType("image/png") | ||
iamjooon2 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
.build(); | ||
try { | ||
s3Client.putObject(objectRequest, RequestBody.fromBytes(getBytes(file))); | ||
} catch (UnsupportedOperationException e) { | ||
throw new IllegalArgumentException("엑세스 접근 중 예외가 발생했습니다."); | ||
iamjooon2 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
|
||
private byte[] getBytes(MultipartFile file) { | ||
try { | ||
return file.getBytes(); | ||
} catch (IOException e) { | ||
throw new IllegalArgumentException("바이트 파싱 중 에러가 발생했습니다."); | ||
iamjooon2 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package zipgo.image.presentaion; | ||
|
||
import java.net.URI; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RequestPart; | ||
import org.springframework.web.bind.annotation.RestController; | ||
import org.springframework.web.multipart.MultipartFile; | ||
import zipgo.image.application.ImageService; | ||
import zipgo.image.presentaion.dto.ImageResponse; | ||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
@RequestMapping("/images") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ImageController라 하니깐 공용 image 처리하는거 같지 않나용 반려동물 controller에 있는게 더 좋을거 같아요 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이거 일단 4차 데모까지 사진 업로드 사용하는 게 여기밖에 없어서 사실상 공용 이미지 처리가 가능하긴 합니다🫠 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 근데 사실 이미지는 도메인 자체를 분리해서 이렇게 쓰는것도 괜찮은듯요 |
||
public class ImageController { | ||
|
||
private final ImageService imageService; | ||
|
||
@PostMapping | ||
public ResponseEntity<ImageResponse> upload( | ||
@RequestPart(required = false, value = "image") MultipartFile imageFile | ||
) { | ||
String url = imageService.save(imageFile); | ||
return ResponseEntity.created(URI.create(url)).body(ImageResponse.from(url)); | ||
} | ||
|
||
iamjooon2 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package zipgo.image.presentaion.dto; | ||
|
||
public record ImageResponse ( | ||
String imageUrl | ||
) { | ||
|
||
public static ImageResponse from(String url) { | ||
return new ImageResponse(url); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package zipgo.pet.application; | ||
|
||
import org.springframework.web.multipart.MultipartFile; | ||
|
||
public interface ImageClient { | ||
iamjooon2 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
String upload(String name, MultipartFile file); | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package zipgo.pet.application; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
import zipgo.member.domain.Member; | ||
import zipgo.member.domain.repository.MemberRepository; | ||
import zipgo.pet.domain.Breeds; | ||
import zipgo.pet.domain.Pet; | ||
import zipgo.pet.domain.PetSize; | ||
import zipgo.pet.domain.repository.BreedsRepository; | ||
import zipgo.pet.domain.repository.PetRepository; | ||
import zipgo.pet.domain.repository.PetSizeRepository; | ||
import zipgo.pet.presentation.dto.request.CreatePetRequest; | ||
|
||
@Service | ||
@Transactional | ||
@RequiredArgsConstructor | ||
public class PetService { | ||
|
||
private final PetRepository petRepository; | ||
private final MemberRepository memberRepository; | ||
private final BreedsRepository breedsRepository; | ||
private final PetSizeRepository petSizeRepository; | ||
|
||
public Long createPet(Long memberId, CreatePetRequest request) { | ||
Member owner = memberRepository.getById(memberId); | ||
PetSize petSize = petSizeRepository.getByName(request.petSize()); | ||
Breeds breeds = breedsRepository.getByNameAndPetSizeId(request.breed(), petSize.getId()); | ||
|
||
Pet pet = petRepository.save(request.toEntity(owner, breeds)); | ||
return pet.getId(); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,23 @@ | ||
package zipgo.pet.domain; | ||
|
||
import java.util.Arrays; | ||
import lombok.RequiredArgsConstructor; | ||
import zipgo.pet.exception.PetException; | ||
|
||
@RequiredArgsConstructor | ||
public enum Gender { | ||
|
||
MALE, | ||
FEMALE; | ||
MALE("남"), | ||
FEMALE("여"), | ||
; | ||
|
||
private final String value; | ||
|
||
public static Gender from(String other) { | ||
return Arrays.stream(values()) | ||
.filter(gender -> gender.value.equals(other)) | ||
.findFirst() | ||
.orElseThrow(PetException.GenderNotFound::new); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,16 @@ | ||
package zipgo.pet.domain.repository; | ||
|
||
import java.util.Optional; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import zipgo.pet.domain.Breeds; | ||
import zipgo.pet.exception.PetException; | ||
|
||
public interface BreedsRepository extends JpaRepository<Breeds, Long> { | ||
|
||
Optional<Breeds> findByNameAndPetSizeId(String name, Long petSizeId); | ||
|
||
default Breeds getByNameAndPetSizeId(String name, Long petSizeId) { | ||
return findByNameAndPetSizeId(name, petSizeId).orElseThrow(PetException.BreedsNotFound::new); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,16 @@ | ||
package zipgo.pet.domain.repository; | ||
|
||
import java.util.Optional; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import zipgo.pet.domain.PetSize; | ||
import zipgo.pet.exception.PetException; | ||
|
||
public interface PetSizeRepository extends JpaRepository<PetSize, Long> { | ||
|
||
Optional<PetSize> findByName(String name); | ||
|
||
default PetSize getByName(String name) { | ||
return findByName(name).orElseThrow(PetException.PetSizeNotFound::new); | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
키야~ 감탄하고갑니다;; 야무지게 분리해놨노