├── .gitignore ├── README.adoc ├── pom.xml └── src └── main ├── java └── com │ └── refactorizando │ └── hexagonalarchitecture │ ├── application │ ├── repository │ │ └── UserRepository.java │ └── service │ │ └── UserService.java │ ├── domain │ └── User.java │ └── infrastructure │ ├── config │ └── spring │ │ ├── SpringBootService.java │ │ └── SpringBootServiceConfig.java │ ├── db │ └── springdata │ │ ├── config │ │ └── SpringDataConfig.java │ │ ├── dbo │ │ └── UserEntity.java │ │ ├── mapper │ │ └── UserEntityMapper.java │ │ └── repository │ │ ├── SpringDataUserRepository.java │ │ └── UserDboRepository.java │ └── rest │ └── spring │ ├── dto │ └── UserDto.java │ ├── mapper │ └── UserMapper.java │ └── resources │ └── Resources.java └── resources └── properties.yml /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .project 3 | target/ 4 | bin/ 5 | .settings/ 6 | .idea/ 7 | *.iml 8 | /src/main/java/com/stratio/financial/onetradeoperations/infrastructure/rest/spring/dto/ 9 | /src/main/java/com/stratio/financial/onetradeoperations/infrastructure/rest/spring/spec/ 10 | .swagger-codegen/ 11 | .openapi-generator/ 12 | .openapi-generator-ignore 13 | .swagger-codegen-ignore 14 | 15 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | = Hexagonal Architecture with Spring Data Example = 2 | 3 | This is an simple example about how to build an application with Hexagonal Architecture in a Spring Data Application. 4 | 5 | This application uses a H2 Data Base, wich is a Data Base in memory. 6 | 7 | If you want more information you can take a look in this post: https://refactorizando.com/ejemplo-de-arquitectura-hexagonal/ 8 | 9 | == How to run it? 10 | 11 | ``` 12 | mvn spring-boot:run 13 | 14 | ``` 15 | 16 | 17 | == How can I test it? 18 | 19 | you have two different endpoints: 20 | 21 | Get - http://localhost:8080/users/user/{userId} 22 | 23 | Post - http://localhost:8080/users 24 | 25 | 26 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.refactorizando 8 | spring-data-hexagonal-architecture 9 | 1.0-SNAPSHOT 10 | 11 | org.springframework.boot 12 | spring-boot-starter-parent 13 | 2.3.0.RELEASE 14 | 15 | 16 | 17 | 11 18 | ${java.version} 19 | ${java.version} 20 | 1.2.0.Final 21 | 22 | 23 | 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-web 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-data-jpa 32 | 33 | 34 | com.h2database 35 | h2 36 | runtime 37 | 38 | 39 | org.projectlombok 40 | lombok 41 | true 42 | 43 | 44 | org.mapstruct 45 | mapstruct-jdk8 46 | ${mapstruct.version} 47 | 48 | 49 | org.mapstruct 50 | mapstruct-processor 51 | ${mapstruct.version} 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/main/java/com/refactorizando/hexagonalarchitecture/application/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.refactorizando.hexagonalarchitecture.application.repository; 2 | 3 | import com.refactorizando.hexagonalarchitecture.domain.User; 4 | 5 | public interface UserRepository { 6 | 7 | User findById(Long id); 8 | 9 | User save(User user); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/refactorizando/hexagonalarchitecture/application/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.refactorizando.hexagonalarchitecture.application.service; 2 | 3 | import com.refactorizando.hexagonalarchitecture.application.repository.UserRepository; 4 | import com.refactorizando.hexagonalarchitecture.domain.User; 5 | import lombok.RequiredArgsConstructor; 6 | import lombok.extern.slf4j.Slf4j; 7 | 8 | @RequiredArgsConstructor 9 | @Slf4j 10 | public class UserService { 11 | 12 | private final UserRepository userRepository; 13 | 14 | public User getUser(Long id) { 15 | 16 | return userRepository.findById(id); 17 | } 18 | 19 | public User saveUser(User user) { 20 | 21 | return userRepository.save(user); 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/refactorizando/hexagonalarchitecture/domain/User.java: -------------------------------------------------------------------------------- 1 | package com.refactorizando.hexagonalarchitecture.domain; 2 | 3 | 4 | public class User { 5 | 6 | private Long id; 7 | 8 | private String name; 9 | 10 | private String address; 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/refactorizando/hexagonalarchitecture/infrastructure/config/spring/SpringBootService.java: -------------------------------------------------------------------------------- 1 | package com.refactorizando.hexagonalarchitecture.infrastructure.config.spring; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.domain.EntityScan; 6 | 7 | @SpringBootApplication(scanBasePackages = "com.refactorizando.hexagonalarchitecture.infrastructure") 8 | @EntityScan(basePackages = "com.refactorizando.hexagonalarchitecture.domain") 9 | public class SpringBootService { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(SpringBootService.class, args); 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /src/main/java/com/refactorizando/hexagonalarchitecture/infrastructure/config/spring/SpringBootServiceConfig.java: -------------------------------------------------------------------------------- 1 | package com.refactorizando.hexagonalarchitecture.infrastructure.config.spring; 2 | 3 | 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | import com.refactorizando.hexagonalarchitecture.application.repository.UserRepository; 8 | import com.refactorizando.hexagonalarchitecture.application.service.UserService; 9 | 10 | @Configuration 11 | public class SpringBootServiceConfig { 12 | 13 | 14 | @Bean 15 | public UserService userService(UserRepository userRepository) { 16 | return new UserService(userRepository); 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/java/com/refactorizando/hexagonalarchitecture/infrastructure/db/springdata/config/SpringDataConfig.java: -------------------------------------------------------------------------------- 1 | package com.refactorizando.hexagonalarchitecture.infrastructure.db.springdata.config; 2 | 3 | import org.springframework.boot.autoconfigure.domain.EntityScan; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.data.jpa.repository.config.EnableJpaAuditing; 7 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 8 | 9 | import lombok.Getter; 10 | import lombok.NoArgsConstructor; 11 | import lombok.Setter; 12 | import lombok.extern.slf4j.Slf4j; 13 | 14 | @Configuration 15 | @EnableJpaRepositories( 16 | basePackages = "com.refactorizando.hexagonalarchitecture.infrastructure.db.springdata.repository") 17 | @ConfigurationProperties("spring.datasource") 18 | @Slf4j 19 | @NoArgsConstructor 20 | @Getter 21 | @Setter 22 | @EnableJpaAuditing 23 | @EntityScan(basePackages = "com.refactorizando.hexagonalarchitecture.infrastructure.db.springdata.dbo") 24 | public class SpringDataConfig { 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/refactorizando/hexagonalarchitecture/infrastructure/db/springdata/dbo/UserEntity.java: -------------------------------------------------------------------------------- 1 | package com.refactorizando.hexagonalarchitecture.infrastructure.db.springdata.dbo; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.Id; 5 | 6 | import lombok.Getter; 7 | import lombok.NoArgsConstructor; 8 | import lombok.Setter; 9 | 10 | @Entity 11 | @Getter 12 | @Setter 13 | @NoArgsConstructor 14 | public class UserEntity { 15 | 16 | @Id 17 | private Long id; 18 | 19 | private String name; 20 | 21 | private String address; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/refactorizando/hexagonalarchitecture/infrastructure/db/springdata/mapper/UserEntityMapper.java: -------------------------------------------------------------------------------- 1 | package com.refactorizando.hexagonalarchitecture.infrastructure.db.springdata.mapper; 2 | 3 | import org.mapstruct.Mapper; 4 | 5 | import com.refactorizando.hexagonalarchitecture.domain.User; 6 | import com.refactorizando.hexagonalarchitecture.infrastructure.db.springdata.dbo.UserEntity; 7 | 8 | @Mapper(componentModel = "spring") 9 | public interface UserEntityMapper { 10 | 11 | User toDomain(UserEntity userEntity); 12 | 13 | UserEntity toDbo(User user); 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/refactorizando/hexagonalarchitecture/infrastructure/db/springdata/repository/SpringDataUserRepository.java: -------------------------------------------------------------------------------- 1 | package com.refactorizando.hexagonalarchitecture.infrastructure.db.springdata.repository; 2 | 3 | 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import com.refactorizando.hexagonalarchitecture.infrastructure.db.springdata.dbo.UserEntity; 8 | 9 | @Repository 10 | public interface SpringDataUserRepository extends JpaRepository { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/refactorizando/hexagonalarchitecture/infrastructure/db/springdata/repository/UserDboRepository.java: -------------------------------------------------------------------------------- 1 | package com.refactorizando.hexagonalarchitecture.infrastructure.db.springdata.repository; 2 | 3 | import java.util.Optional; 4 | 5 | import org.springframework.stereotype.Service; 6 | 7 | import com.refactorizando.hexagonalarchitecture.application.repository.UserRepository; 8 | import com.refactorizando.hexagonalarchitecture.domain.User; 9 | import com.refactorizando.hexagonalarchitecture.infrastructure.db.springdata.mapper.UserEntityMapper; 10 | import com.refactorizando.hexagonalarchitecture.infrastructure.rest.spring.mapper.UserMapper; 11 | 12 | import lombok.RequiredArgsConstructor; 13 | 14 | 15 | @RequiredArgsConstructor 16 | @Service 17 | public class UserDboRepository implements UserRepository { 18 | 19 | private final SpringDataUserRepository userRepository; 20 | 21 | private final UserEntityMapper userMapper; 22 | 23 | @Override 24 | public User findById(Long id) { 25 | return userMapper.toDomain(userRepository.findById(id).orElseThrow()); 26 | } 27 | 28 | @Override 29 | public User save(User user) { 30 | 31 | return userMapper.toDomain(userRepository.save(userMapper.toDbo(user))); 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/refactorizando/hexagonalarchitecture/infrastructure/rest/spring/dto/UserDto.java: -------------------------------------------------------------------------------- 1 | package com.refactorizando.hexagonalarchitecture.infrastructure.rest.spring.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import lombok.Setter; 7 | 8 | @Getter 9 | @Setter 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class UserDto { 13 | 14 | private Long id; 15 | 16 | private String name; 17 | 18 | private String address; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/refactorizando/hexagonalarchitecture/infrastructure/rest/spring/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.refactorizando.hexagonalarchitecture.infrastructure.rest.spring.mapper; 2 | 3 | import org.mapstruct.Mapper; 4 | 5 | import com.refactorizando.hexagonalarchitecture.domain.User; 6 | import com.refactorizando.hexagonalarchitecture.infrastructure.rest.spring.dto.UserDto; 7 | 8 | @Mapper(componentModel = "spring") 9 | public interface UserMapper { 10 | 11 | UserDto toDto (User user); 12 | 13 | User toDomain(UserDto userDto); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/refactorizando/hexagonalarchitecture/infrastructure/rest/spring/resources/Resources.java: -------------------------------------------------------------------------------- 1 | package com.refactorizando.hexagonalarchitecture.infrastructure.rest.spring.resources; 2 | 3 | import org.springframework.http.HttpStatus; 4 | import org.springframework.http.ResponseEntity; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.PathVariable; 7 | import org.springframework.web.bind.annotation.PostMapping; 8 | import org.springframework.web.bind.annotation.RequestBody; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | import com.refactorizando.hexagonalarchitecture.application.service.UserService; 12 | import com.refactorizando.hexagonalarchitecture.infrastructure.rest.spring.dto.UserDto; 13 | import com.refactorizando.hexagonalarchitecture.infrastructure.rest.spring.mapper.UserMapper; 14 | import lombok.RequiredArgsConstructor; 15 | 16 | @RequiredArgsConstructor 17 | @RestController 18 | public class Resources { 19 | 20 | private final UserService userService; 21 | 22 | private final UserMapper userMapper; 23 | 24 | @GetMapping("users/user/{id}") 25 | public ResponseEntity getUserById(@PathVariable Long id) { 26 | 27 | return new ResponseEntity<>(userMapper.toDto(userService.getUser(id)), HttpStatus.OK); 28 | 29 | } 30 | 31 | @PostMapping("users") 32 | public ResponseEntity saveUser(@RequestBody UserDto userDto) { 33 | 34 | return new ResponseEntity<>(userMapper.toDto(userService.saveUser(userMapper.toDomain(userDto))), 35 | HttpStatus.CREATED); 36 | 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/resources/properties.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:h2:mem:testdb 4 | driverClassName: org.h2.Driver 5 | username: sa 6 | password: password 7 | 8 | spring.jpa.database-platform=org.hibernate.dialect.H2Dialect 9 | --------------------------------------------------------------------------------