Open ForNeVeR opened 6 years ago
Раунд второй.
Инфраструктура:
app-run.bat
: gradlew build && java -jar build/libs/my-app-0.1.0.jar
— разве gradlew run
делает не то же самое?form-info-data-example.sql
: название поля "fileds"
— опечатка?Бэкенд:
@Autowired
устарели, и нужно инжектить вещи через конструктор — мол, Spring team recommends. Предлагаю это исправить.MainController::index
до сих пор возвращает Hello World
— наверное, можно уже там сделать что-то вменяемое :)UsersController::users
: (type != null ? Arrays.asList(type) : Arrays.asList(User.Type.values()))
— я считаю, что даже этот кусочек логики было бы лучше унести в сервис, а не выполнять его в контроллере.UserRole
и UserType
? Нет ли тут дублирования функциональности?BaseEntity
. Сейчас я не рекомендую наследовать все сущности от одного класса.Frontend:
user.ts
, userRole.ts
: мне кажется, должны быть интерфейсами, а не классами.Фронтенд я особо эффективно поревьюить не смог, потому что у меня не очень много опыта в работе с новым Angular.
IDEA (которой я теперь доверяю 😉) говорит, что инъекции через @Autowired устарели, и нужно инжектить вещи через конструктор — мол, Spring team recommends. Предлагаю это исправить.
Т.е. вместо
@RestController
public class EmailController {
@Autowired
private EmailService emailService;
...
надо
@RestController
public class EmailController {
private EmailService emailService;
public EmailController(EmailService emailService) {
this.emailService = emailService;
}
?
Да. Только в определение поля ещё можно добавить final
: private EmailService emailService;
Если что, в IDE есть быстрофикс для того, чтобы автоматически заполнить поле из конструктора :)
Инженерные детали по этому поводу: DI-фреймворк (в нашем случае Spring) умеет вызывать конструкторы сервисов, подбирая для них зависимости из своего контекста. Это считается более правильным, чем использование аннотаций на полях, потому что так сложнее сделать ошибку, а в стороннем коде (в тестах, например) можно будет создавать сервисы без использования Spring.
Общие замечания по проекту:
По коду и архитектуре бэкенда:
UserController::users
— мне кажется, не хватает пажинации. Сложно представить, что мы хоть в какой-то системе захотим отдавать список объектов из БД целиком. (Для этого посмотри на стандартный спринговыйPagingAndSortingRepository
.)UserController::delete
: ты сначала запрашиваешь пользователя, а потом его удаляешь. Если между этими действиями с ним что-то случится — будет плохо (одновременные запросы на удаление, скорее всего, упадут с ошибкой). Желательно защищаться от этого хотя бы repeatable read-транзакцией. (И, понятное дело,@Transactional
тоже напрашивается в метод сервиса, а не контроллера.)Вот тут плохой код: https://github.com/dorofeev22/caregiving/blob/1d5b5f014e4eae61ec837574191e8967e4b2a9b4/src/main/java/ru/dorofeev22/caregiving/controllers/UserController.java#L62
Ты объявляешь переменную непонятного типа
Optional
, хотя стоило бы сделатьOptional<User>
. На следующей строке у меня IDE показывает ворнинг.К тому же, этот метод мне вообще не нравится — получаешь безопасный тип
Optional<User>
, а потом разворачиваешь его вnull
. Будто прям напрашиваешься наNullPointerException
! Предлагаю его убрать, и везде юзатьOptional<User>
, который получен тобой из репозитория (конкретные примеры работы могу подсказать, только спроси).По фронтенду:
Помимо этого, можно озадачиться и настроить Swagger. Это автоматически генерируемая страничка для твоего API, которая выглядит примерно вот так: http://petstore.swagger.io/
Получается, что для тестирования API не нужно никаких дополнительных инструментов и вообще ничего, кроме, собственно, браузера. Наши тестировщики очень любят эту штуку и не стесняются вызывать API-методы при тестировании напрямую (без UI наших мобильных и браузерных приложений). Я считаю, что разработчику при отладке эта штука тоже не помешает.
По базе данных:
LC_COLLATE = 'Russian_Russia.1251'
. Выглядит это очень стрёмно, нет ли там стандартной русской юникодовой collate?