이 글은 인프런 강의 "Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)"를 정리한 글입니다. 문제/오류가 있을 시 댓글로 알려주시면 감사드리겠습니다
강의의 모든 부분을 정리하는 것이 아니고 비슷한 부분은 생략합니다
ApiGateway-Service
server:
port: 8000
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url :
defaultZone: http://localhost:8761/eureka
spring:
application:
name: apigateway-service
cloud:
gateway:
default-filters:
- name : GlobalFilter # Component 이름
args :
baseMessage : Spring Cloud Gateway Global Filter
preLogger : true
postLogger : true
routes:
- id: first-service
uri: lb://MY-FIRST-SERVICE
predicates:
- Path=/first-service/**
filters:
- CustomFilter
- id: second-service
uri: lb://MY-SECOND-SERVICE
predicates:
- Path=/second-service/**
filters:
- name: CustomFilter
- name: LoggingFilter
args:
baseMessage: Hi, there
preLogger: true
postLogger: true
- id: catalog-service
uri: lb://CATALOG-SERVICE
predicates:
- Path=/catalog-service/**
filters:
- CustomFilter
- id: user-service
uri: lb://USER-SERVICE
predicates:
- Path=/user-service/**
filters:
- CustomFilter
- id: order-service
uri: lb://ORDER-SERVICE
predicates:
- Path=/order-service/**
filters:
catalog-service, user-service, order-service에 대해서 라우팅 기능을 추가한다
UserService
uri 값이 달라 apigateway를 사용할 때와 안할 때의 차이가 난다
@RestController
@RequestMapping("/user-service/")
public class UserController {
...
}
@RestController
@RequestMapping("/user-service/")
public class UserController {
... 생략
@GetMapping("/health_check")
public String status(){
//포트번호를 출력할 수 있도록 변경
return String.format("It's Working in User Service on Port %s", env.getProperty("local.server.port"));
}
// 회원가입
@PostMapping("/users")
public ResponseEntity<ResponseUser> createUser(@RequestBody RequestUser user){
...
}
// userList
@GetMapping("/users")
public ResponseEntity<List<ResponseUser>> getUsers(){
Iterable<UserEntity> userList = userService.getUserByAll();
List<ResponseUser> result = new ArrayList<>();
userList.forEach(v -> {
result.add(new ModelMapper().map(v, ResponseUser.class));
});
return ResponseEntity.status(HttpStatus.OK).body(result);
}
//userId 를 전달하면 세부사항을 전달하도록 함
@GetMapping("/users/{userId}")
public ResponseEntity<ResponseUser> getUser(@PathVariable("userId") String userId){
UserDto userDto= userService.getUserByUserId(userId);
ResponseUser returnValue = new ModelMapper().map(userDto, ResponseUser.class);
return ResponseEntity.status(HttpStatus.OK).body(returnValue);
}
}
@Data
public class UserDto {
... 생략
private List<ResponseOrder> orders;
}
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResponseUser {
... 생략
private List<ResponseOrder> orders;
}
package com.zzarbttoo.userservice.vo;
import lombok.Data;
import java.util.Date;
@Data
public class ResponseOrder {
private String productId;
private Integer qty;
private Integer unitPrice;
private Integer totalPrice;
private Date createAt;
private String orderId;
}
@Service
public class UserServiceImpl implements UserService{
... 생략
@Override
public UserDto getUserByUserId(String userId) {
UserEntity userEntity = userRepository.findByUserId(userId);
if(userEntity == null){
//spring security
throw new UsernameNotFoundException("User not found");
}
UserDto userDto = new ModelMapper().map(userEntity, UserDto.class);
List<ResponseOrder> orders = new ArrayList<>();
userDto.setOrders(orders);
return userDto;
}
@Override
public Iterable<UserEntity> getUserByAll() {
return userRepository.findAll();
}
}
package com.zzarbttoo.userservice.jpa;
import org.springframework.data.repository.CrudRepository;
//CRUD 작업을 하기 때문에 CrudRepository 상속
//Entity 정보 입력, 기본키 classType 입력
public interface UserRepository extends CrudRepository<UserEntity, Long> {
UserEntity findByUserId(String userId);
}
Catalog-service
... 생략
spring:
application:
name: catalog-service
h2:
console:
enabled: true
settings:
web-allow-others: true
path: /h2-console
jpa:
hibernate:
ddl-auto : create-drop
show-sql : true
generate-ddl : true
database: h2
datasource:
driver-class-name: org.h2.Driver
url : jdbc:h2:mem:testdb
...
#logging level 지정
logging:
level:
com.zzarbttoo.catalogservice : DEBUG
insert into catalog(product_id, product_name, stock, unit_price)
values('CATALOG-001', 'Berlin', 100, 1500);
insert into catalog(product_id, product_name, stock, unit_price)
values('CATALOG-002', 'Tokyo', 110, 1000);
insert into catalog(product_id, product_name, stock, unit_price)
values('CATALOG-003', 'Stockholm', 120, 2000);
Order Service
... 생략
spring:
application:
name: order-service
h2:
console:
enabled: true
settings:
web-allow-others: true
path: /h2-console
jpa:
hibernate:
ddl-auto : update #초기 데이터를 추가하지 않을 것
database: h2
datasource:
driver-class-name: org.h2.Driver
...
@Slf4j
@RestController
@RequestMapping("/order-service")
public class OrderController {
Environment env;
OrderService orderService;
@Autowired
public OrderController(Environment env, OrderService orderService) {
this.env = env;
this.orderService = orderService;
}
@GetMapping("/health_check")
public String status(){
//포트번호를 출력할 수 있도록 변경
return String.format("It's Working in Catalog Service on Port %s", env.getProperty("local.server.port"));
}
//http://127.0.0.1:0/order-service/{user_id}/orders/
@PostMapping("/{userId}/orders")
public ResponseEntity<ResponseOrder> createOrder(@PathVariable("userId") String userId, @RequestBody RequestOrder requestOrder){
log.info("requestOrder ::: " + requestOrder.toString());
ModelMapper mapper = new ModelMapper();
mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
OrderDto orderDto = mapper.map(requestOrder, OrderDto.class);
log.info("orderDto ::: " + orderDto.toString());
orderDto.setUserId(userId);
OrderDto createdOrder = orderService.createOrder(orderDto);
ResponseOrder responseOrder = mapper.map(createdOrder, ResponseOrder.class);
log.info("responseOrder ::: " + responseOrder);
return ResponseEntity.status(HttpStatus.CREATED).body(responseOrder);
}
@GetMapping("/{userId}/orders")
public ResponseEntity<List<ResponseOrder>> getOrder(@PathVariable("userId") String userId){
Iterable<OrderEntity> orderList = orderService.getOrdersByUserId(userId);
List<ResponseOrder> result = new ArrayList<>();
orderList.forEach(v -> {
result.add(new ModelMapper().map(v, ResponseOrder.class));
});
return ResponseEntity.status(HttpStatus.OK).body(result);
}
}