【问题标题】:consuming rest api from springboot, architecture question从 Spring Boot 中使用 rest api,架构问题
【发布时间】:2020-12-16 02:09:12
【问题描述】:

我想用 springBoot MVC 写一个 REST API 客户端。客户端将向 API 发送数据请求,并将其显示到浏览器中。例如,我将 http://example.com/showItems 映射到 itemsController.show 方法并由 item.html (thymeleaf) 模板呈现。

我的问题是在哪里放置 API 调用以及如何处理 API 响应。 我正在考虑设计,而不仅仅是让它发挥作用。还假设我想扩展到许多返回不同对象的 API 调用。

我正在考虑几个选项:

  • 控制器内的 WebClient。控制器处理返回项目对象的 API 调用。
  • 项目类负责 API 调用。并且可能会调整结果以进行渲染。不同的对象有不同的 API 调用。也许所有人都注入了相同的 WebClient
  • 我创建了一个 itemService,其中包含一个“DAO”,一个调用 API 并返回项目对象的 itemDAO。类似于 DAO 存储库 + 模型。

我不确定采用哪种解决方案。在春季是否有另一种常见的方法,或者其他一些设计模式?或者每种解决方案的优缺点是什么?

【问题讨论】:

    标签: spring-boot model-view-controller design-patterns


    【解决方案1】:

    在spring boot中遵循MVC的结构有很多方法 在这里,我有一个解决方案,您可以在哪里跟进


    这是我的文件结构

    UserController 和 @RestController //所有 Get 和 Post API 调用

    UserService with @Service //Define Business Logic here

    UserRegistrationReqBean @Data //用于 Lombok 并减少样板文件

    UserMaster @Entity //对于表架构

    • UserMasterRepo @Repository //用于 Jpa 查询

      • UserMasterDao //与服务层交互以进行数据库查询的接口

        • UserMasterDaoImpl @Component //用于Dao接口定义

    首先创建一个控制器类(例如我正在使用用户管理系统)

    @RestController
    @RequestMapping("/v1.0")
    public class UserController {
    
        @Autowired
        UserService userService;
    
        @GetMapping("/getUsers")
        public List<UserMaster> getUsers() {
            return userService.getUsers();
        }
    
        @PostMapping("/registerUser")
        public UserMaster registerUser(@RequestBody RegisterUserReqBean reqBean) {
            return userService.registerUser(reqBean);
        }
    
    //  @PostMapping("/updateUser")
    //  public UserMaster updateUser() {
    //      UserMaster updatedUser = new UserMaster();
    //      return updatedUser;
    //  }
    
    }
    

    一旦您创建了控制器,然后在 Service 层中使用 @Service Annotation 定义其业务逻辑

    @Service
    public class UserService {
    
        @Autowired
        UserMasterDao userMasterDao;
    
        public List<UserMaster> getUsers() {
            List<UserMaster> listOfUser = userMasterDao.findAll();
            return listOfUser;
        }
    
        public UserMaster registerUser(RegisterUserReqBean reqBean) {
            UserMaster userMaster = new UserMaster(reqBean);
            UserMaster updatedUserMaster = userMasterRepo.save(userMaster);
            return updatedUserMaster;
        }
    
    //  public UserMaster updateUser() {
    //
    //  }
    }
    

    创建一个带有@Repository 注解的 Repo 类来做一些 db 相关的更改

    import org.springframework.data.jpa.repository.JpaRepository;
    
    import com.sample.user.entity.UserMaster;
    
        @Repository
        public interface UserMasterRepo extends JpaRepository<UserMaster, Integer> {
        
    //you can create your own JPA queries here
        }
    

    这里我的存储库是空的,因为我正在使用它的预定义查询

    than 使用定义数据库表模式的@Entity 注释实现实体类 使用 ma​​ven Lombok 依赖 减少 Entity 和请求 Bean 中的样板代码

        @Entity
        @Data
        @Table(name = "kd_user_master")
        public class UserMaster {
        
            @Id
            @GeneratedValue(strategy = GenerationType.IDENTITY)
            @Column(name = "user_id")
            private Integer userId;
        
            @Column(name = "first_name")
            private String firstName;
        
            @Column(name = "last_name")
            private String lastName;
        
            @Column(name = "user_name")
            private String userName;
        
            @Column(name = "email")
            private String email;
        
            @Column(name = "mobile_number")
            private String mobileNumber;
        
            @Column(name = "password")
            private String password;
        
            @Column(name = "country")
            private String country;
        
            @Column(name = "created_at")
            private Date createdAt;
        
            @Column(name = "updated_at")
            private Date updatedAt;
    
    //this parameterized cunstructer is used for having new object of userMaster //schema so we can directly save it to db 
    public UserMaster(RegisterUserReqBean reqBean) {
            super();
            this.firstName = reqBean.getFirstName();
            this.lastName = reqBean.getLastName();
            this.userName = reqBean.getUserName();
            this.email = reqBean.getEmail();
            this.mobileNumber = reqBean.getMobileNumber();
            this.password = reqBean.getPassword();
            this.country = reqBean.getCountry();
            this.createdAt = new Date();
            this.updatedAt = new Date();
        }
        }
    

    然后我们将创建一个DAO(数据访问对象)接口及其实现类

    public interface UserMasterDao{
    
    UserMaster save(userMaster user);
    
    List<UserMaster> findAll();
    }
    

    它的实现类

    public class UserMasterDaoImpl implements UserMasterDao{
    
    @Autowired
    UserMasterRepo repo;
    
    @Override
    UserMaster save(UserMaster user){
    return repo.save(user);
    }
    
    
    @Override
    List<UserMaster> findAll(){
    return repo.findAll();
    }
    }
    

    在业务逻辑和数据库模式之后,我们需要为发布请求定义请求 bean,因为它不允许我们请求参数,或者我们可以说查询参数

    @Data
    public class RegisterUserReqBean {
    
        private String firstName;
    
        private String lastName;
    
        private String userName;
    
        private String email;
    
        private String mobileNumber;
    
        private String password;
    
        private String country;
    
        private Date createdAt;
    
        private Date updatedAt;
    }
    

    我们在控制器类和服务类中使用这个请求 bean 来进行用户注册

    【讨论】:

    • 好吧,其实我想CONSUME一个外部API,spring应用真的是一个客户端。
    【解决方案2】:

    一般来说,所有的业务逻辑和任何 API 调用都应该在服务层中完成。您应该在配置类中配置其他服务 bean 并在服务层(适当的 mvc 架构)中进行调用,一旦获得响应,您可以根据您的要求对其进行更改,然后将其返回给控制器。

    【讨论】:

      猜你喜欢
      • 2022-11-03
      • 2021-03-07
      • 1970-01-01
      • 2020-09-04
      • 2016-09-16
      • 2019-06-28
      • 2020-02-22
      • 2018-03-29
      • 2020-07-29
      相关资源
      最近更新 更多