Какой шаблон получения информации в Spring Boot Application @RestController лучше и как указать ЛЮБОЙ @Mapping?

У меня есть @RestController в приложении Spring Boot.

@PutMapping("{table}/{key}")
    public void update(@PathVariable("tables") String tableName,
                               @PathVariable("key") String key,
                               @RequestBody Entity entity) {
    ... 
    }

Более удобно преобразовать это отображение в:

@PutMapping("{table}/{key}")
        public void update(@RequestBody Entity entity) {
        ... 
        }

и ожидать, что информация из @PathVariable будет внутри @RequestBody.

Причина: У меня есть другой @RestController, в котором я получаю AnotherEntity anotherEntity. Этот стиль архитектуры позволяет мне создавать общая иерархия в сервисных слоях.

Вопрос 1: Разве это не плохой паттерн? Это достаточно хорошо, как идеальный сервис ОТДЫХ, или мне следует избегать его? вопрос 2: в этом случае я не использую @PathVariable, и мне просто нужно указать какое-то слово/другое слово как @PutMappingдорожка. Есть ли способ указать что-то вроде любой/любой без интеллектуальной проверки, которую я должен использовать?

Обновление: пример архитектуры

public abstract class Validator<T> {
    public abstract void validate(T t);
}

public class FirstEntityValidator extends Validator<FirstEntity> {
     public void validate(FirstEntity entity){
     ...
     }
}

public class SecondEntityValidator extends Validator<SecondEntity> {
     public void validate(SecondEntity entity){
     ...
     }
}

public abstract class EntityService<T> {

    private Validator<T> validator;

    public EntityService(Validator<T> validator){
      this.validator = validator;
    }
}

public class FirstEntityService extends EntityService<FirstEntity> {

    public FirstEntityService(FirstEntityValidator<FirstEntity> validator){
       super(validator);
    }
}

public class SecondEntityService extends EntityService<SecondEntity> {

    public SecondEntityService(SecondEntityValidator<SecondEntity> validator){
       super(validator);
    }
}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
70
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я бы избегал чего-то подобного. Вы должны разделить свои контроллеры REST так же, как вы разделяете свои службы. В случае, если вам нужно что-то изменить только для одной сущности, вам все равно придется рефакторить все или создать какой-то уродливый код.

Я думаю, что вы пытаетесь представить свои репозитории как веб-сервис REST. Spring может справиться с этим за вас. Проверь это: https://docs.spring.io/spring-data/rest/docs/current/reference/html/

Используйте интерфейсы. Не используйте абстрактные классы. В этом нет необходимости, и это может быть очень сложно реализовать в больших проектах.

Это было бы лучше:

public interface class Validator<T> {
  void validate(T t);
}

public class FirstEntityValidator implements Validator<FirstEntity> {
   public void validate(FirstEntity entity){
   ....
   }
}


public class SecondEntityValidator implements Validator<SecondEntity> {
   public void validate(SecondEntity entity){
   ....
   }
}

public interface EntityService{

 //your methods....

}

public class FirstEntityService implements EntityService{

    private FirstEntityValidator validator;

    public FirstEntityService(FirstEntityValidator validator){
        this.validator = validator;
    }

}

Есть еще одна проблема — информация из @RequestBody и @PathVariable может отличаться. Вы сказали о возможных изменениях, но если у меня есть 2 службы для 2 разных объектов (служба - это что-то абстрактное, это может быть распределенная служба, служба кэширования и т. д.), и у них один и тот же метод? Отличие только одно - тип параметра. С одной стороны у меня есть копипаста. С другой стороны, если я использую AbstractService с типом T, у меня могут возникнуть проблемы в будущем. Похоже, оба варианта не совсем хороши

Donatello 09.03.2019 23:49

Не используйте абстрактные службы. Используйте композицию. Это очень поможет вам в будущем. Прочтите это: en.wikipedia.org/wiki/Composition_over_inheritance

DCO 09.03.2019 23:58

а как насчет принципа подстановки Лисков?

Donatello 10.03.2019 00:01

Это то, чему я научился в своем последнем большом проекте. Наследование больше не должно использоваться. Вы можете сделать все в композиции, что сделает ваш проект более удобным в сопровождении

DCO 10.03.2019 00:02

Принцип единой ответственности javacodegeeks.com/2014/02/… Я думаю, это то, чему разработчики научились за последние 10 лет. Наследование может быть полезным. Но почти во всех случаях композиция — лучший выбор.

DCO 10.03.2019 00:07

Я просто хочу указать, подходит ли это для моего примера. Я добавил пример в вопросе: это плохая архитектура? Я прячу все за общим интерфейсом и избегаю копипаста, но я неопытен и очень этим интересуюсь. Не могли бы вы проверить, пожалуйста?

Donatello 10.03.2019 00:22

У меня последний вопрос - в своем ответе вы указали валидатор как тип FirstEntityValidator внутри сервиса. Почему вы не указали It как тип интерфейса Validator?

Donatello 10.03.2019 01:19

Вы можете сделать это, конечно. Я просто хотел показать вам, что вы используете конкретную реализацию в этом сервисе.

DCO 10.03.2019 01:58

Другие вопросы по теме