#spring-boot #model-view-controller #design-patterns
#spring-boot #модель-представление-контроллер #шаблоны проектирования
Вопрос:
Я хочу написать клиент REST API с SpringBoot MVC. Клиент отправит запрос к API для получения данных и покажет их в браузере. Например, у меня будетhttp://example.com/showItems сопоставлен с itemsController.показать метод и визуализировать с помощью item.html шаблон (thymeleaf).
Мой вопрос в том, куда поместить вызов API и как обращаться с ответом API. Я думаю о дизайне, а не просто заставляю его работать. Давайте также представим, что я хочу расширить до многих вызовов API, возвращающих разные объекты.
Я думаю о нескольких вариантах:
- веб-клиент внутри контроллера. Контроллер обрабатывает вызовы API, которые возвращают объект item.
- класс item обрабатывает вызов API. И, возможно, адаптация результата для рендеринга. Разные объекты имеют разные вызовы API. Возможно, все они внедрили один и тот же веб-клиент
- Я создаю ItemService, который содержит «DAO», itemDAO, который вызывает API и возвращает объекты item. Аналогично репозиторию DAO модели.
Я не уверен, какое решение принять. Есть ли другой распространенный способ сделать это в spring или какой-либо другой шаблон проектирования? Или каковы могут быть плюсы / минусы каждого решения?
Ответ №1:
Существует множество подходов к использованию структуры MVC в spring boot, здесь у меня есть решение, для которого вы можете следовать этому
вот моя файловая структура
Пользовательский контроллер с @RestController //Все вызовы API Get и Post
Пользовательский сервис с помощью @Service // Определяет бизнес-логику здесь
UserRegistrationReqBean @Data //для Lombok и для уменьшения шаблонности
Мастер пользователя @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
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, чтобы внести некоторые изменения, связанные с БД
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
}
Здесь мой репозиторий пуст, поскольку я использую его предопределенные запросы
чем реализует класс сущности с @Entity
аннотацией, которая определяет схему таблицы базы данных, используйте зависимость maven Lombok для сокращения шаблонного кода в сущности и компоненте запроса
@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();
}
}
После бизнес-логики и схемы базы данных нам нужно определить компонент запроса для запроса post, поскольку он не позволяет нам запрашивать параметры, или мы можем сказать параметры запроса
@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;
}
мы используем этот компонент запроса в классе контроллера, а также в классе обслуживания для регистрации пользователей
Комментарии:
1. ну, на самом деле я хочу использовать внешний API, приложение Spring на самом деле является клиентом.
Ответ №2:
Как правило, вся бизнес-логика и любые вызовы API должны выполняться на уровне сервиса. Вы должны настроить другой компонент service в классе configuration и выполнить вызов на уровне service (надлежащая архитектура mvc), и как только вы получите ответ, вы можете изменить его на основе ваших требований, а затем вернуть его контроллеру.