У меня есть один класс контроллера Spring REST, который имеет несколько конечных точек. Является ли хорошей практикой прямой вызов метода конечной точки из другой конечной точки?
Я погуглил, но не нашел ответа на вопрос, что является хорошей практикой для решения этой проблемы.
@RestController
public class DataContoller {
@GetMapping("/dataA/{param}")
public ResponseEntity getDataA(@PathVariable String param) {
// logic to fetch data A
return ResponseEntity.ok("A");
}
@GetMapping("/dataB/{param}")
public ResponseEntity getDataB(@PathVariable String param) {
ResponseEntity response = getDataA("test");
String result = response.getBody();
return ResponseEntity.ok("B" + result);
}
}
В принципе, это работает, поскольку это просто вызов метода из другого метода, но я хотел бы знать, является ли это хорошей практикой или нет. И если это не очень хорошая практика, то какой идеальный способ сделать это. Один из вариантов — использование RestTemplate. Это единственный вариант?
Привет, Дженс. Приведенный выше код, вероятно, не является хорошим примером, но я застрял в реальной ситуации, когда одна конечная точка требуется для вызова другой, поскольку для продолжения необходимы эти данные.
Вы должны обрабатывать это на сервисном уровне
Если два метода должны получить одни и те же данные одним и тем же способом, извлеките метод fetchData, поместите его в службу, внедрите службу в свой контроллер и вызовите метод из двух методов контроллера. methodA не нуждается в ResponseEntity, созданном методом B. Им просто нужно получить одни и те же данные.




Это не так уж плохо, но и не хорошо.
Проблема в том, что прямой вызов getDataA("test") пропускает все, что обычно предшествует методу этого контроллера: проверки безопасности, валидацию, фильтрацию, регистрацию, сопоставление или любые другие виды манипуляций с данными.
Это вносит нестабильность: вы не уверены, какие данные поступают и откуда они на самом деле. Это пришло из моего внутреннего метода или это был HTTP-вызов?
Очень простой совет — иметь сервисный метод getDataA и вызывать его из обоих методов контроллера. Однако, как вы уже заметили, он не полностью заменяет HTTP-запрос.
Спасибо Андрей за ваш комментарий. Даже если я перенесу логику на сервисный уровень и вызову метод сервисного уровня вместо контроллера, это все равно будет означать, что я пропускаю проверку безопасности, проверку, регистрацию или сопоставление. Я хочу сказать, что вызов одного метода контроллера из другого выглядит уродливо, кроме того, что если один метод заинтересован только в результате другого, то почему бы не вызвать метод контроллера напрямую.
Я согласен с тем, что вы говорите в середине вашего комментария, но я не согласен с этой частью skips everything that normally precedes this controller's method: security checks, validation, filtering, logging, mapping, or any other kind of data manipulation. В идеале контроллеры должны обрабатывать только делегирование HTTP-запроса на уровень службы и не выполнять никаких других функций. Есть и другие компоненты, которые служат этой цели.
@Aris_Kortex мы говорим об одном и том же. Под «всем» я подразумеваю «любой другой компонент» — я категорически против возложения ответственности за безопасность/фильтрацию/и т. д. на контроллер.
Нет, это не так. И я думаю, что это не имеет смысла. То, что вы пытаетесь сделать, означает, что у вас есть две конечные точки, которые делают одно и то же.