├── .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 |
--------------------------------------------------------------------------------