当前位置:Java -> 实施最佳实践:使用Spring Boot构建微服务API
首先,让我们详细解释一下架构。让我们详细了解每个层次。
让我详细解释一下架构。这些组件通常与遵循领域驱动设计(DDD)和模型-视图-控制器(MVC)或类似架构模式的应用架构相关联。我逐一介绍:
实体代表应用程序中的核心业务对象或概念。它们封装与业务领域相关的数据。例如,在员工管理系统中,员工实体可能具有与员工相关的名称、电子邮件和薪资等属性。
存储库负责处理数据访问逻辑。它们提供对数据存储的抽象,允许应用程序与数据交互,而无需担心底层存储细节。例如,EmployeeRepository 将处理数据库中员工记录的存储、检索、更新和删除操作。
服务包含在实体方法内部无法自然适应的业务逻辑。它们协调实体和存储库之间的交互,以执行更高级别的用例。例如,EmployeeService 可能具有用于计算奖金、处理员工调动或处理涉及多个实体的复杂业务规则的方法。
映射器负责在应用程序的不同层之间转换数据。它们将数据从数据库实体转换为域对象,反之亦然。例如,EmployeeMapper 可能将员工实体转换为可以通过网络发送或由表示层使用的数据传输对象(EmployeeRequest)。
控制器处理来自用户界面或外部系统的输入请求。它们解释用户输入,调用必要的服务或业务逻辑,并准备要发送回去的响应。在 web 应用程序中,控制器接收 HTTP 请求,提取必要的数据,并将请求委托给适当的服务。然后格式化服务响应并将其发送回客户端。
前端:您可以选择构建原生应用,如 Android 和 iOS。可以使用 React 或 Angular 框架构建桌面浏览器应用程序或移动浏览器应用程序。
@ManyToOne
引用其他表。请记住,表的创建是自动的,实体中的写入内容很重要。@OneToMany
双向关联,以便在一次调用中保存多个表中的值。@ManyToMany
连接表。如果加入表除了加入 id 列以外还有其他字段,则创建一个单独的 Join 类。package org.project.feature.entities;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "users")
public class Users {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(length = 100, nullable = false)
private String firstName;
@Column(length = 100, nullable = false)
private String lastName;
@Column(length = 100, nullable = false, unique = true)
private String email;
}
JpaRepository
扩展为实体名称和 ID 为 LongfindByEmail
saveAll
package org.project.feature.repositories;
import org.project.feature.entities.Users;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UsersRepository extends JpaRepository<Users, Long> {
}
@AllArgsConstructor
替代 @Autowired
注解package org.project.feature.services;
import org.project.feature.models.UsersRequest;
import org.project.feature.models.UsersResponse;
import java.util.List;
public interface UsersService {
UsersResponse createUser(UsersRequest usersRequest);
UsersResponse getUserById(Long userId);
List<UsersResponse> getAllUsers();
UsersResponse updateUser(Long id, UsersRequest users);
void deleteUser(Long userId);
}
package org.project.feature.services.impl;
import lombok.AllArgsConstructor;
import org.project.feature.entities.Users;
import org.project.feature.mappers.UsersMapper;
import org.project.feature.models.UsersRequest;
import org.project.feature.models.UsersResponse;
import org.project.feature.repositories.UsersRepository;
import org.project.feature.services.UsersService;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@Service
@AllArgsConstructor
public class UsersServiceImpl implements UsersService {
private final UsersRepository usersRepository;
private final UsersMapper usersMapper;
@Override
public UsersResponse createUser(UsersRequest usersRequest) {
Users users = usersMapper.convertRequestToEntity(usersRequest);
Users saved = usersRepository.save(users);
return usersMapper.convertEntityToResponse(saved);
}
@Override
public UsersResponse getUserById(Long userId) {
Optional<Users> optionalUser = usersRepository.findById(userId);
return usersMapper.convertEntityToResponse(optionalUser.get());
}
@Override
public List<UsersResponse> getAllUsers() {
List<Users> users = usersRepository.findAll();
List<UsersResponse> usersResponses = new ArrayList<>();
for (Users user : users)
usersResponses.add(usersMapper.convertEntityToResponse(user));
return usersResponses;
}
@Override
public UsersResponse updateUser(Long id, UsersRequest usersRequest) {
Optional<Users> user = usersRepository.findById(id);
Users existingUsers = user.orElse(null);
existingUsers.setFirstName(usersRequest.getFirstName());
existingUsers.setLastName(usersRequest.getLastName());
existingUsers.setEmail(usersRequest.getEmail());
Users updatedUsers = usersRepository.save(existingUsers);
return usersMapper.convertEntityToResponse(updatedUsers);
}
@Override
public void deleteUser(Long userId) {
usersRepository.deleteById(userId);
}
}
package org.project.feature.mappers;
import org.project.feature.entities.Users;
import org.project.feature.models.UsersRequest;
import org.project.feature.models.UsersResponse;
import org.springframework.stereotype.Component;
@Component
public class UsersMapper {
public UsersResponse convertEntityToResponse(Users users) {
UsersResponse usersResponse = new UsersResponse();
usersResponse.setId(users.getId());
usersResponse.setFirstName(users.getFirstName());
usersResponse.setLastName(users.getLastName());
usersResponse.setEmail(users.getEmail());
return usersResponse;
}
public Users convertRequestToEntity(UsersRequest usersRequest) {
Users users = new Users();
users.setFirstName(usersRequest.getFirstName());
users.setLastName(usersRequest.getLastName());
users.setEmail(usersRequest.getEmail());
return users;
}
}
package org.project.feature.models;
import jakarta.persistence.Column;
import lombok.Data;
import java.io.Serializable;
@Data
public class UsersRequest implements Serializable {
private String firstName;
private String lastName;
private String email;
}
package org.project.feature.models;
import jakarta.persistence.Column;
import lombok.Data;
import java.io.Serializable;
@Data
public class UsersResponse implements Serializable {
private Long id;
private String firstName;
private String lastName;
private String email;
}
package org.project.feature.controllers;
import lombok.AllArgsConstructor;
import org.project.feature.models.UsersRequest;
import org.project.feature.models.UsersResponse;
import org.project.feature.services.UsersService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@AllArgsConstructor
@RequestMapping("/api/users")
public class UsersController {
private final UsersService usersService;
@PostMapping
public ResponseEntity<UsersResponse> createUser(@RequestBody UsersRequest usersRequest){
UsersResponse savedUsers = usersService.createUser(usersRequest);
return new ResponseEntity<>(savedUsers, HttpStatus.CREATED);
}
@GetMapping("{id}")
public ResponseEntity<UsersResponse> getUserById(@PathVariable("id") Long userId){
UsersResponse users = usersService.getUserById(userId);
return new ResponseEntity<>(users, HttpStatus.OK);
}
@GetMapping
public ResponseEntity<List<UsersResponse>> getAllUsers(){
List<UsersResponse> users = usersService.getAllUsers();
return new ResponseEntity<>(users, HttpStatus.OK);
}
@PutMapping("{id}")
public ResponseEntity<UsersResponse> updateUser(@PathVariable("id") Long userId,
@RequestBody UsersRequest usersRequest){
UsersResponse updatedUsers = usersService.updateUser(userId, usersRequest);
return new ResponseEntity<>(updatedUsers, HttpStatus.OK);
}
@DeleteMapping("{id}")
public ResponseEntity<String> deleteUser(@PathVariable("id") Long userId){
usersService.deleteUser(userId);
return new ResponseEntity<>("User successfully deleted!", HttpStatus.OK);
}
}
从长远的角度来看,随着代码基础变得庞大,您可能需要使用Strangler模式将一些服务独立出来,并将其部署为单独的微服务。这种编码结构将有所帮助。如果您从一开始就把基础打好,那么以后的道路将会更加顺畅。
推荐阅读: 5.了解ARP协议吗?
本文链接: 实施最佳实践:使用Spring Boot构建微服务API