Java Spring boot Api: поведение контроллера в зависимости от параметра запроса - PullRequest
0 голосов
/ 01 декабря 2018

По сути, я вынужден использовать URL-адрес пути следующим образом GET /accounts/<accountNumber::string>/reports?type=<DAILY>&date=<YYYY-MM-DD> Дело в том, что мое поведение сильно зависит от типа моего отчета, как вы можете видеть "Ежедневно" в моем примере.Поэтому я ищу шаблон проектирования, который позволил бы мне смоделировать фабрику контроллеров, которая бы создавала конкретные контроллеры для каждого из моих типов отчетов.Например, у меня будет DefaultController, имеющий метод getReport, который будет сопоставлен с моим GET-запросом и который делегирует другим конкретным контроллерам (например, DailyReportController) задачу генерации и возврата отчета.

Я хочумой дизайн должен быть максимально зависимым от принципов SOLID и других чистых кодов и принципов обслуживания.Поэтому, даже если бы я добавил тип отчета через месяц, все, что мне понадобилось бы, это добавить новый TypeReportController и значение в моем перечислении ReportType, а не иметь бесконечные методы в моем контроллере и моих службах

1 Ответ

0 голосов
/ 01 декабря 2018

Я прочитал ваше описание.Но я думаю, что может быть одна конечная точка контроллера, и ваш контроллер выберет другую реализацию сервиса.Например, если ваш параметр DAILY , он выберет DailyReportServiceImpl и выберет другую реализацию в зависимости от типа вашего отчета.Вы можете попробовать следующий дизайн:

@RestController
@RequestMapping
public class ReportController {

    @Autowired
    ReportService reportService;

    @GetMapping(value = "/accounts/{accountNumber}/reports")
    public Report getReport(@PathParam("accountNumber") String accountNumber,
                              @RequestParam("type") String type,@RequestParam("date")Date date){

        if(ReportEnum.DAILY.name().equals(type))
        {
            reportService = new DailyReportServiceImpl();
        }else if(ReportEnum.MONTHLY.name().equals(type)){
            reportService = new MonthlyReportService();
        }
        return reportService.getReport();
    }
}

И объявить интерфейс для служб:

public interface ReportService {
    public Report getReport();
}

А затем реализовать эту службу из dailyreportservice и других служб: DailyReportServiceImpl willбудет выглядеть так:

public class DailyReportServiceImpl implements ReportService {
    @Override
    public Report getReport() {
        return null;
    }
}

MonthlyReportService будет выглядеть так:

public class MonthlyReportService implements ReportService {
    @Override
    public Report getReport() {
        return null;
    }
}

Объявите класс отчета:

public class Report {
}

, затем вынеобходимо определить enum:

public enum ReportEnum {
    DAILY("DAILY"),
    MONTHLY("MONTHLY"),
    YEARLY("YEARLY");

    private String name;

    ReportEnum(String name) {
        this.name = name;
    }

    public String getName() {
        return name();
    }
}

NB: : В любом случае, у вас есть конкретная причина для определения другой конечной точки контроллера?

Если да, вы можете определить конечные точки другим способом:вот так.

@RestController
@RequestMapping
public class ReportController {

    @Autowired
    ReportService reportService;

    @GetMapping(value = "/accounts/{accountNumber}/reports/DAILY")
    public Report getReportDaily(@PathParam("accountNumber") String accountNumber,
                              @RequestParam("date")Date date){
        reportService = new DailyReportServiceImpl();
        return reportService.getReport();
    }
    @GetMapping(value = "/accounts/{accountNumber}/reports/MONTHLY")
    public Report getReportMonthly(@PathParam("accountNumber") String accountNumber,
                              @RequestParam("date")Date date){
        reportService = new MonthlyReportService();
        return reportService.getReport();
    }
}

Но я думаю, что предыдущий - лучший дизайн.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...