Skip to content

Commit

Permalink
Merge pull request #106 from Recipe-Project/feature/add_readme
Browse files Browse the repository at this point in the history
readme 파일 추가, swagger 3 업그레이드
  • Loading branch information
joona95 authored Aug 12, 2024
2 parents 3e69036 + 9895299 commit c227b73
Show file tree
Hide file tree
Showing 15 changed files with 290 additions and 243 deletions.
99 changes: 99 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# 🍅 레시피 저장소

<br>
<p align="center">
<img src = https://github.com/Recipe-Project/RecipeServer/assets/39457533/2dc442f4-83ee-4423-8a4e-21df261f26a1 height="180" width="180" />
</p>
<br>
<br>


- 프로젝트 기간 : 2021.02 ~
- 댜운로드 URL : https://play.google.com/store/apps/details?id=com.recipe.android.recipeapp&hl=ko-KR

<br>

## 프로젝트 소개

- 레시피 저장소는 냉장고에 있는 재료를 등록하여 유통기한, 수량 등 재고 관리를 가능하게 해주는 서비스입니다.
- 냉장고에 있는 재료들을 기반으로 재료 일치도에 따라 레시피를 추천해줍니다.
- 검색을 통해 블로그, 유튜브, 공공 레시피를 찾아볼 수 있습니다.
- 나만의 레시피를 등록하여 레시피 관리를 할 수 있습니다.

<br>

## 팀 구성

### 레시피 저장소 v 1.0

안드로이드 | 안드로이드 | 백엔드 | 백엔드 | 디자인
-|-|-|-|-
[@Jsueeee](https://github.com/Jsueeee) | [@Boin-Kau](https://github.com/Boin-Kau) | [@joona95](https://github.com/joona95) | [@kimmjieun](https://github.com/kimmjieun) | @hailey

### 레시피 저장소 v 2.0 (진행중)

안드로이드 | 백엔드 | 디자인
-|-|-
[@Jsueeee](https://github.com/Jsueeee) | [@joona95](https://github.com/joona95) | @hailey

- develop branch 에서 진행중
- 전체 구조 및 코드 리팩토링 진행
- 새로운 기능 추가
- 디자인 및 기획 변경 반영

<br>

## 사용 기술

- Java
- Spring Boot
- Spring Security
- JPA
- Querydsl
- MySQL
- Redis
- swagger 3
- AWS (EC2, RDS, Elasticache)
- Github Actions


<br>

## 아키텍처

<img width="694" alt="스크린샷 2024-08-12 오후 9 16 10" src="https://github.com/user-attachments/assets/b510f190-5933-4ea3-9cd3-73614e1a7e1f">

## ERD

<img width="1633" alt="스크린샷 2024-08-12 오후 9 33 58" src="https://github.com/user-attachments/assets/0a7a7d42-91b3-4d16-82a0-4742ed6281bb">

## API 명세서

<img width="1244" alt="스크린샷 2024-08-12 오후 11 58 37" src="https://github.com/user-attachments/assets/465fb51c-6641-48bb-8589-d54c9ad8ba28">

- 개발 서버: https://recipestorage.shop:9090/swagger-ui/index.html
- 로컬: http://localhost:9090/swagger-ui/index.html

## UI

### 레시피 저장소 v 1.0

<img src = https://github.com/user-attachments/assets/7f3d4bad-c4fc-4b20-89d2-e22a4810ef24 height="600" width="300" />
<img src = https://github.com/user-attachments/assets/44c87870-d62a-4ecd-b223-ca5287903931 height="600" width="300" />
<img src = https://github.com/user-attachments/assets/bfa7c31b-d7e3-4adb-b632-ff823eb0e0c5 height="600" width="300" />
<img src = https://github.com/user-attachments/assets/5645b6cf-c6ee-4e80-9b48-a0a49767e158 height="600" width="300" />
<img src = https://github.com/user-attachments/assets/892b4812-9ec6-4869-9d68-7c2e85160cc2 height="600" width="300" />
<img src = https://github.com/user-attachments/assets/662c6c43-04fd-4220-a603-d33b4271f4e6 height="600" width="300" />


### 레시피 저장소 V 2.0

<img width="300" height="600" src="https://github.com/user-attachments/assets/91c53dfb-d077-4efa-9065-f79076e4845f">
<img width="300" height="600" src="https://github.com/user-attachments/assets/701c8b5a-2c41-4e0b-a2e5-87143651606c">
<img width="300" height="600" src="https://github.com/user-attachments/assets/2c8540d2-e5ce-42ff-ac49-62a0a52da8e4">
<img width="300" height="600" src="https://github.com/user-attachments/assets/824a1e80-893b-4f84-a1fb-a2eda4e1e0f8">
<img width="300" height="600" src="https://github.com/user-attachments/assets/9be9f784-7da8-403f-a7f0-3eabdc26c18e">
<img width="300" height="600" src="https://github.com/user-attachments/assets/f4017b2d-c104-4b17-98c7-87e9bef18079">
<img width="300" height="600" src="https://github.com/user-attachments/assets/6231ef79-dc4d-44b9-a568-3ae25006d50b">
<img width="300" height="600" src="https://github.com/user-attachments/assets/e160b985-d2b0-401d-9d25-bfde14d30efc">

2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ dependencies {

implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:4.1.0'

implementation 'io.springfox:springfox-boot-starter:3.0.0'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'

testImplementation 'org.springframework.boot:spring-boot-starter-test'

Expand Down
83 changes: 21 additions & 62 deletions src/main/java/com/recipe/app/src/config/SwaggerConfig.java
Original file line number Diff line number Diff line change
@@ -1,77 +1,36 @@
package com.recipe.app.src.config;

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RestController;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.RequestParameterBuilder;
import springfox.documentation.schema.ScalarType;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ParameterType;
import springfox.documentation.service.RequestParameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Arrays;

@EnableSwagger2
@Import(BeanValidatorPluginsConfiguration.class)
@OpenAPIDefinition(
info = @Info(title = "레시피 저장소 API 명세서",
description = "레시피 저장소 API 목록",
version = "1.0")
)
@Configuration
public class SwaggerConfig {

@Bean
public Docket api() {
RequestParameter parameter = new RequestParameterBuilder()
.name("X-ACCESS-TOKEN")
.in(ParameterType.HEADER)
.query(p -> p.model(m -> m.scalarModel(ScalarType.STRING)))
.description("Authorization Header")
.required(false)
.build();
public OpenAPI openAPI() {

List<RequestParameter> parameters = new ArrayList<>();
parameters.add(parameter);
SecurityScheme securityScheme = new SecurityScheme()
.type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT")
.in(SecurityScheme.In.HEADER).name("Authorization");

return new Docket(DocumentationType.SWAGGER_2)
.globalRequestParameters(parameters)
.useDefaultResponseMessages(false)
.consumes(getConsumeContentTypes())
.produces(getProduceContentTypes())
.select()
.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo());
}

private Set<String> getConsumeContentTypes() {
Set<String> consumes = new HashSet<>();
consumes.add("application/json;charset=UTF-8");
consumes.add("application/x-www-form-urlencoded");
return consumes;
}
SecurityRequirement securityRequirement = new SecurityRequirement().addList("bearerAuth");

private Set<String> getProduceContentTypes() {
Set<String> produces = new HashSet<>();
produces.add("application/json;charset=UTF-8");
return produces;
}
return new OpenAPI()
.components(new Components().addSecuritySchemes("bearerAuth", securityScheme))
.security(Arrays.asList(securityRequirement));

private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("레시피 저장소 API 명세서")
.description("레시피 저장소 API 목록")
.version("1.0")
.build();
}
}
31 changes: 15 additions & 16 deletions src/main/java/com/recipe/app/src/fridge/api/FridgeController.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
import com.recipe.app.src.fridge.application.dto.FridgeResponse;
import com.recipe.app.src.fridge.application.dto.FridgesResponse;
import com.recipe.app.src.user.domain.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
Expand All @@ -17,9 +17,8 @@
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

@Api(tags = {"냉장고 Controller"})
@Tag(name = "냉장고 Controller")
@RestController
@RequestMapping("/fridges")
public class FridgeController {
Expand All @@ -30,44 +29,44 @@ public FridgeController(FridgeService fridgeService) {
this.fridgeService = fridgeService;
}

@ApiOperation(value = "냉장고 채우기 API")
@Operation(summary = "냉장고 채우기 API")
@PostMapping
@LoginCheck
public void postFridges(@ApiIgnore User user) {
public void postFridges(@Parameter(hidden = true) User user) {

fridgeService.create(user);
}

@ApiOperation(value = "냉장고 목록 조회 API")
@Operation(summary = "냉장고 목록 조회 API")
@GetMapping
@LoginCheck
public FridgesResponse getFridges(@ApiIgnore User user) {
public FridgesResponse getFridges(@Parameter(hidden = true) User user) {

return fridgeService.getFridges(user);
}

@ApiOperation(value = "냉장고 상세 조회 API")
@Operation(summary = "냉장고 상세 조회 API")
@GetMapping("/{fridgeId}")
@LoginCheck
public FridgeResponse getFridge(@ApiIgnore User user, @PathVariable Long fridgeId) {
public FridgeResponse getFridge(@Parameter(hidden = true) User user, @PathVariable Long fridgeId) {

return fridgeService.getFridge(user, fridgeId);
}

@ApiOperation(value = "냉장고 삭제 API")
@Operation(summary = "냉장고 삭제 API")
@DeleteMapping("/{fridgeId}")
@LoginCheck
public void deleteFridge(@ApiIgnore User user, @PathVariable Long fridgeId) {
public void deleteFridge(@Parameter(hidden = true) User user, @PathVariable Long fridgeId) {

fridgeService.delete(user, fridgeId);
}

@ApiOperation(value = "냉장고 수정 API")
@Operation(summary = "냉장고 수정 API")
@PatchMapping("/{fridgeId}")
@LoginCheck
public void patchFridge(@ApiIgnore User user,
public void patchFridge(@Parameter(hidden = true) User user,
@PathVariable Long fridgeId,
@ApiParam(value = "냉장고 수정 입력 정보", required = true)
@Parameter(name = "냉장고 수정 입력 정보", required = true)
@RequestBody FridgeRequest request) {

fridgeService.update(user, fridgeId, request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
import com.recipe.app.src.fridgeBasket.application.dto.FridgeBasketsRequest;
import com.recipe.app.src.fridgeBasket.application.dto.FridgeBasketsResponse;
import com.recipe.app.src.user.domain.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
Expand All @@ -18,9 +18,8 @@
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

@Api(tags = {"냉장고 바구니 Controller"})
@Tag(name = "냉장고 바구니 Controller")
@RestController
@RequestMapping("/fridges/basket")
public class FridgeBasketController {
Expand All @@ -31,46 +30,46 @@ public FridgeBasketController(FridgeBasketService fridgeBasketService) {
this.fridgeBasketService = fridgeBasketService;
}

@ApiOperation(value = "재료 선택하여 냉장고 바구니 채우기 API")
@Operation(summary = "재료 선택하여 냉장고 바구니 채우기 API")
@PostMapping
@LoginCheck
public void postFridgeBasketByIngredientId(@ApiIgnore User user,
@ApiParam(value = "재료 선택 목록", required = true)
@RequestBody FridgeBasketsRequest request) {
public void postFridgeBasketByIngredientId(@Parameter(hidden = true) User user,
@Parameter(name = "재료 선택 목록", required = true)
@RequestBody FridgeBasketsRequest request) {

fridgeBasketService.create(user, request);
}

@ApiOperation(value = "냉장고 바구니 조회 API")
@Operation(summary = "냉장고 바구니 조회 API")
@GetMapping
@LoginCheck
public FridgeBasketsResponse getFridgeBaskets(@ApiIgnore User user) {
public FridgeBasketsResponse getFridgeBaskets(@Parameter(hidden = true) User user) {

return fridgeBasketService.findAllByUser(user);
}

@ApiOperation(value = "냉장고 바구니 삭제 API")
@Operation(summary = "냉장고 바구니 삭제 API")
@DeleteMapping("/{fridgeBasketId}")
@LoginCheck
public void deleteFridgeBasket(@ApiIgnore User user, @PathVariable Long fridgeBasketId) {
public void deleteFridgeBasket(@Parameter(hidden = true) User user, @PathVariable Long fridgeBasketId) {

fridgeBasketService.delete(user, fridgeBasketId);
}

@ApiOperation(value = "냉장고 바구니 수정 API")
@Operation(summary = "냉장고 바구니 수정 API")
@PatchMapping("/{fridgeBasketId}")
@LoginCheck
public void patchFridgeBasket(@ApiIgnore User user, @PathVariable Long fridgeBasketId,
@ApiParam(value = "냉장고 바구니 수정 정보", required = true)
@RequestBody FridgeBasketRequest request) {
public void patchFridgeBasket(@Parameter(hidden = true) User user, @PathVariable Long fridgeBasketId,
@Parameter(name = "냉장고 바구니 수정 정보", required = true)
@RequestBody FridgeBasketRequest request) {

fridgeBasketService.update(user, fridgeBasketId, request);
}

@ApiOperation(value = "냉장고 바구니 갯수 조회 API")
@Operation(summary = "냉장고 바구니 갯수 조회 API")
@GetMapping("/count")
@LoginCheck
public FridgeBasketCountResponse getFridgeBasketCount(@ApiIgnore User user) {
public FridgeBasketCountResponse getFridgeBasketCount(@Parameter(hidden = true) User user) {

return fridgeBasketService.countFridgeBasketByUser(user);
}
Expand Down
Loading

0 comments on commit c227b73

Please sign in to comment.