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

[suffle] Chapter09_API & Swagger & Annotation #38

Merged
merged 9 commits into from
Jun 23, 2024
1 change: 1 addition & 0 deletions src/mission/umc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-validation'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package com.example.umc.common.configuration;

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.servers.Server;
import org.springdoc.core.utils.SpringDocUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.awt.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Collections;

@Configuration
@OpenAPIDefinition
public class SwaggerConfiguration {

private final SecurityScheme securityScheme = new SecurityScheme()
.type(SecurityScheme.Type.APIKEY)
.in(SecurityScheme.In.HEADER)
.name("Authorization");

{
SpringDocUtils.getConfig().replaceWithSchema(Color.class,
new Schema<String>()
.type("string")
.format("color")
.example("#FFFFFFFF"));

SpringDocUtils.getConfig().replaceWithSchema(LocalDateTime.class,
new Schema<LocalDateTime>()
.type("string")
.format("date-time")
.example(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)));

SpringDocUtils.getConfig().replaceWithSchema(LocalDate.class,
new Schema<LocalDate>()
.type("string")
.format("date")
.example(LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE)));

SpringDocUtils.getConfig().replaceWithSchema(LocalTime.class,
new Schema<LocalTime>()
.type("string")
.format("time")
.example(LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))));
}

@Bean
public OpenAPI openApi() {
String description = "umc Swagger setting";
String securityRequirementName = "bearerAuth";

// 파일 업로드를 위한 스웨거 정의 추가
Schema fileSchema = new Schema();
fileSchema.setType("string");
fileSchema.setFormat("binary");

return new OpenAPI()
.servers(Collections.singletonList(new Server().url("/")))
.security(Collections.singletonList(new SecurityRequirement().addList(securityRequirementName)))
.components(new Components()
.addSecuritySchemes(securityRequirementName, securityScheme)
.addSchemas("file", fileSchema)) //파일 스키마 추가
.info(new Info()
.title("API")
.description(description)
.version("0.0.1")
)
.externalDocs(new ExternalDocumentation().description("team-m API"));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.example.umc.domain.Loader;

import com.example.umc.domain.Member;
import com.example.umc.domain.Region;
import com.example.umc.domain.enums.Gender;
import com.example.umc.domain.enums.MemberStatus;
import com.example.umc.domain.enums.SocialType;
import com.example.umc.repository.MemberRepository;
import com.example.umc.repository.RegionRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class DataLoader implements CommandLineRunner {

private final MemberRepository memberRepository;
private final RegionRepository regionRepository;

@Override
public void run(String... args) throws Exception {
Member member = Member.builder()
.name("John Doe")
.address("123 Main St")
.specAddress("Apt 4B")
.gender(Gender.MALE)
.socialType(SocialType.KAKAO) // Assuming SocialType.FACEBOOK is a valid value
.status(MemberStatus.ACTIVE)
.email("[email protected]")
.point(100)
.build();

memberRepository.save(member);

Region region = Region.builder()
.name("Seoul")
.build();
regionRepository.save(region);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@
import com.example.umc.domain.maaping.MemberPrefer;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

@Entity
@Getter
@DynamicUpdate
@DynamicInsert
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Builder
@AllArgsConstructor
Expand Down Expand Up @@ -53,15 +57,19 @@ public class Member extends BaseEntity {

private Integer point;

@Builder.Default
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL)
private List<MemberAgree> memberAgreeList = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL)
private List<MemberPrefer> memberPreferList = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL)
private List<Review> reviewList = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL)
private List<MemberMission> memberMissionList = new ArrayList<>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.List;

@Entity
@Setter
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.example.umc.domain.enums;

import lombok.Getter;

@Getter
public enum MissionStatus {
CHALLENGING, COMPLETE
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ public enum ErrorStatus implements BaseErrorCode {
NICKNAME_ALREADY_EXIST(HttpStatus.BAD_REQUEST, "MEMBER4003", "중복된 닉네임 입니다."),
MEMBER_NOT_FOUND_OR_PASSWORD_ERROR(HttpStatus.BAD_REQUEST, "MEMBER4004", "없는 사용자이거나 비밀번호가 틀렸습니다."),

// 가게 관련 에러
STORE_NOT_FOUND(HttpStatus.BAD_REQUEST, "STORE4001", "가게가 없습니다."),

//지역 관련 에러
REGION_NOT_FOUND(HttpStatus.BAD_REQUEST, "REGION4001", "지역이 없습니다."),

// 미션 관련 에러
MISSION_NOT_FOUND(HttpStatus.BAD_REQUEST, "MISSION4001", "미션을 찾을 수 없습니다."),
MISSION_ALREADY_EXIST(HttpStatus.BAD_REQUEST, "MISSION4002", "이미 존재하는 미션입니다."),

// test
TEMP_EXCEPTION(HttpStatus.BAD_REQUEST, "TEMP4001", "이거는 테스트"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.umc.repository;

import com.example.umc.domain.FoodCategory;
import org.springframework.data.jpa.repository.JpaRepository;

public interface FoodCategoryRepository extends JpaRepository<FoodCategory, Long> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.umc.repository;

import com.example.umc.domain.maaping.MemberMission;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MemberMissionRepository extends JpaRepository<MemberMission, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.umc.repository;

import com.example.umc.domain.Member;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MemberRepository extends JpaRepository<Member, Long> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.umc.repository;

import com.example.umc.domain.Mission;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MissionRepository extends JpaRepository<Mission, Long> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.umc.repository;

import com.example.umc.domain.Region;
import org.springframework.data.jpa.repository.JpaRepository;

public interface RegionRepository extends JpaRepository<Region, Long> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.umc.repository;

import com.example.umc.domain.Review;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ReviewRepository extends JpaRepository<Review, Long> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.umc.repository;

import com.example.umc.domain.Store;
import org.springframework.data.jpa.repository.JpaRepository;

public interface StoreRepository extends JpaRepository<Store, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.example.umc.service;

import com.example.umc.domain.Member;
import com.example.umc.domain.Mission;
import com.example.umc.domain.enums.MissionStatus;
import com.example.umc.domain.maaping.MemberMission;
import com.example.umc.repository.MemberMissionRepository;
import com.example.umc.repository.MemberRepository;
import com.example.umc.repository.MissionRepository;
import com.example.umc.validation.annotation.ExistMission;
import lombok.RequiredArgsConstructor;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.stereotype.Service;

import java.time.LocalDate;

@Service
@RequiredArgsConstructor
public class MemberService {

private final MemberRepository memberRepository;
private final MissionRepository missionRepository;
private final MemberMissionRepository memberMissionRepository;

public void addMission(Long missionId, Long memberId) {
Mission mission = missionRepository.getReferenceById(missionId);
Member member = memberRepository.findById(memberId).orElseThrow(()-> new IllegalArgumentException("Member not found"));

MemberMission memberMission = MemberMission.builder()
.status(MissionStatus.CHALLENGING)
.member(member)
.mission(mission)
.build();

member.getMemberMissionList().add(memberMission);
memberMissionRepository.save(memberMission);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.example.umc.service;

import com.example.umc.domain.Mission;
import com.example.umc.domain.Store;
import com.example.umc.repository.MissionRepository;
import com.example.umc.repository.StoreRepository;
import com.example.umc.web.dto.request.CreateMissionRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class MissionService {

private final StoreRepository storeRepository;
private final MissionRepository missionRepository;

public void addMission(CreateMissionRequest createMissionRequest) {

Store store = storeRepository.getReferenceById(createMissionRequest.getStoreId());
missionRepository.save(CreateMissionRequest.toEntity(createMissionRequest, store));

return;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.example.umc.service;

import com.example.umc.domain.Member;
import com.example.umc.domain.Review;
import com.example.umc.domain.Store;
import com.example.umc.repository.MemberRepository;
import com.example.umc.repository.ReviewRepository;
import com.example.umc.repository.StoreRepository;
import com.example.umc.web.dto.reponse.ReviewResponseDto;
import com.example.umc.web.dto.request.CreateReviewRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
@Slf4j
public class ReviewService {

private final ReviewRepository reviewRepository;
private final MemberRepository memberRepository;
private final StoreRepository storeRepository;

public ReviewResponseDto addReview(CreateReviewRequest createReviewRequest) {
Member member = memberRepository.findById(createReviewRequest.getMemberId())
.orElseThrow(() -> new IllegalArgumentException("Member not found"));

/* Store store = storeRepository.findById(createReviewRequest.getStoreId())
.orElseThrow(() -> new IllegalArgumentException("Store not found"));
이렇게 처리를 할 필요가 없는 거지 이미 유효성 검사를 했기 때문에
*/
Store store = storeRepository.getReferenceById(createReviewRequest.getStoreId());
Review review = CreateReviewRequest.toEntity(createReviewRequest, member, store);
Review savedReview = reviewRepository.save(review);

return ReviewResponseDto.fromEntity(savedReview);
}
}
Loading