v1 Разработка REST API на Spring MVC + Boot
100500 ак. ч., 6 дней.
Записи
Prerequisites
- Installed JDK8
- Installed IntelliJ IDEA Community of Ultimate (preferred)
- Installed Tomcat
Современный гибкий и тестопригодный дизайн
- Пример процедурного legacy-кода и вопросы сопровождаемости
- Внутренняя модель качества
- OOAD как ответ на запрос бизнеса
- Инкапсуляция
- Слои
- Полиморфизм и абстракции
- Зависимости компонентов: порождающие шаблоны
- Spring-ready архитектура
Ключевые концепции Spring Core
- Понятие фреймворка и контейнера
- Разрешение зависимостей компонентов через DI
- Понятие конфигурации и контекста
- Spring Core как AOP framework implementation
- Обзор модулей Spring
Practice Iteration
Given
- Demo application
- Обзор maven-зависимостей
- Настроен максимальный уровень журналирования
When
- Консольным Spring Core приложением реализованы требования
Я, как анонимный банковский сотрудник, хочу создать банковский счет, чтобы он сохранился в системе для дальнейших операций
Я, как анонимный банковский сотрудник, хочу узнать состояние банковского счета по его id, чтобы сообщить клиенту
Я, как анонимный банковский сотрудник, хочу просмотреть все сохраненные счета, чтобы узнать нужный id для дальнейших операций
- Проведены полная очистка проекта и сборка в maven
Then
- Разобраны вопросы и трудности
- Проведен public code review
- Участники отвечают на вопросы
Конфигурация Spring-приложения
-
Структура конфигурации:
-
Annotation-based configuration including JSR 330 and JSR 250 annotations
-
Декларация компонентов
-
Инстациирование компонентов в xml-конфигурации
-
Управление жизненным циклом компонентов: магия
-
Управление жизненным циклом компонентов: scope
-
Управление жизненным циклом компонентов: laziness
-
в xml-конфигурации, включая xml autowiring
-
Вычисления при инициализации контекста на SpEL
-
Профили конфигурации
-
Расширения модели annotation-based configuration
-
Аннотации JSR 330
-
Аннотации JSR 250: ресурсы и обработчики @PostConstruct и @PreDestroy
-
Событийная модель в Spring и встроенные события
-
Управление безопасностью
-
Управление транзакциями
-
Управление повторами операций (ретраинг)
-
Управление асинхронностью
-
Управление кешированием
Reference: Corner Cases for Bean declaration and initialization
Type Switching anti-pattern
Declaration
- Два бина с одинаковым id в одной секции beans: ошибка инициалиазации контекста
- Два бина с одинаковым id в разных секциях beans (два xml или профили в одном xml): последний заданный overrides первый
- Бин, заданный в xml без id, ищется только по типу
- Бин, заданный в xml без id, не инъектируется через @Autowired. Надо ref в xml
- Бин, заданный как @Component, автоматом получает id. @Component("newId") overrides дефолтный id
- Бин с дублирующимся id, определенный в xml, overrides бин, заданный как @Component
- Бин с дублирующимся id, определенный в @Configuration, overrides бин, заданный как @Component
- Бин с дублирующимся id, определенный в @Configuration и xml: берется из xml, skipping определение из @Configuration
- Бин с дублирующимся id, определенный в @Configuration, xml и как @Component: берется из xml, skipping определение из @Configuration
Initialization
- Eager service1 depending on eager service2
23:25:10.331 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'service1'
23:25:10.346 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'service2'
......context loaded and prepared......
Getting service1
Got service1
Result of service1's operation call: 84
- Lazy service1 depending on eager service2
23:26:00.941 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'service2'
......context loaded and prepared......
Getting service1
23:26:00.966 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'service1'
Got service1
Result of service1's operation call: 84
- Eager service1 depending on lazy service2
23:26:51.508 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'service1'
23:26:51.524 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'service2'
......context loaded and prepared......
Getting service1
Got service1
Result of service1's operation call: 84
- Lazy service1 depending on lazy service2
......context loaded and prepared......
Getting service1
23:27:41.133 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'service1'
23:27:41.146 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'service2'
Got service1
Result of service1's operation call: 84
Scopes
- Singleton service1 depending on singleton service2
23:45:54.740 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'service1'
S1 object constructor
23:45:54.773 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'service2'
S2 object constructor
......context loaded and prepared......
Getting service1
Got service1
Result of service1's operation call: 84
Result of service1's operation call: 84
Getting service1
Got service1
Result of service1's operation call: 84
Result of service1's operation call: 84
- Singleton service1 depending on prototype service2
S1 object constructor
S2 object constructor
......context loaded and prepared......
Getting service1
Got service1
Result of service1's operation call: 84
Result of service1's operation call: 84
Getting service1
Got service1
Result of service1's operation call: 84
Result of service1's operation call: 84
- Prototype service1 depending on singleton service2
23:47:43.826 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'service2'
S2 object constructor
......context loaded and prepared......
Getting service1
S1 object constructor
Got service1
Result of service1's operation call: 84
Result of service1's operation call: 84
Getting service1
S1 object constructor
Got service1
Result of service1's operation call: 84
Result of service1's operation call: 84
- Prototype service1 depending on Prototype service2
......context loaded and prepared......
Getting service1
S1 object constructor
S2 object constructor
Got service1
Result of service1's operation call: 84
Result of service1's operation call: 84
Getting service1
S1 object constructor
S2 object constructor
Got service1
Result of service1's operation call: 84
Result of service1's operation call: 84
Practice Iteration
Given
- Demo application
- Консольное Spring-приложение
When
- Консольным Spring Core приложением реализованы требования
Я, как администратор, хочу вынести в конфигурацию размер страницы вывода
Я, как анонимный банковский сотрудник, хочу просмотреть все сохраненные счета c первой страницы вывода, чтобы узнать нужный id
Я, как анонимный банковский сотрудник, хочу видеть в консольном журнале все события создания счетов
Я, как анонимный банковский сотрудник, хочу видеть в консольном журнале все события запроса счетов
Я, как администратор, хочу видеть порядок создания компонентов
Я, как администратор, хочу видеть конкретное имя класса всех управляемых компонентов в журнале
Then
- Разобраны вопросы и трудности
- Проведен public code review
- Участники отвечают на вопросы
Введение в протокол HTTP и JavaEE/JakartaEE web-приложения
HTTP
- Протокол HTTP
- Методы запросов
- Параметры и аргументы запросов
- Заголовки
- Статусы ответов
- Cookies
JavaEE/JakartaEE
- Web/Servlet-контейнеры
- Компоненты веб-приложения
- Управляемые объекты
- Структура JavaEE web-приложений
Spring MVC
- Архитектура Spring MVC и ее редукция для REST API
- Конфигурация
- Контроллеры
- Меппинги на URL
- Параметры в URL
- JSON де/сериализация объектов
- JSON Mapper
- Basic mapping annotations
- Обработка и афиширование ошибок
Practice Iteration
Given
- Демо протокола HTTP
- Демо web-контейнера Tomcat
- Сборка и развертывание демо-приложения на web-контейнере
- Отладка HTTP-запросов и ответов в REST-клиенте в IDEA
When
- Реализован HTTP API к существующим операциям
- Приложение собрано как war
- Приложение вручную развернуто на Tomcat
- HTTP API протестирован в REST-клиенте IDEA
Then
- Разобраны вопросы и трудности
- Проведен public code review
- Участники отвечают на вопросы
Концепция REST API и Spring RESTful Services
- Сравнение RPC и REST
- Принципы проектирования REST API
- Идемпотентность и безопасность операций HTTP
- API Design Patterns
- Ограничения REST API и GraphQL
Practice Iteration
Given
- Реализованный HTTP API
When
- Произведен рефакторинг API в соответствии с архитектурой REST
- Реализованы требования
Я, как администратор, хочу легко переключать профили конфигурации приложения
- REST API протестирован в REST-клиенте IDEA
Then
- Разобраны вопросы и трудности
- Проведен public code review
- Участники отвечают на вопросы
Spring Boot
- Задачи Boot
- авто-конфигурация типовых компонентов
- вывод конфигурационных данных в простой конфиг
- авто-конфигурация подключаемых повторно используемых модулей (starters) с кодом и конфигурацией
- транзитивные зависимости модулей
- CLI для разработки и тестирования
CLI Boot Applications
- Подключение Boot в проект и настройка сборщика
- Модули и их подключение
- Структура приложения и точка входа
- Запуск boot-приложения
- Конфигурация Boot-приложения
- Конфигурационные профили
- пример с настройкой компонентов
- Поддержка в IDEA
MVC Boot Applications
Practice Iteration
Given
- Конструктор заготовок Spring Boot приложений
- Демо плагина анализа конфигурации в IDEA
- Demo application
- Реализованный REST API
When
- Произведен рефакторинг миграции приложения на платформу Spring Boot
- Конфигурация проанализирована в специализированном плагине IDEA
- REST API протестирован в REST-клиенте IDEA
Then
- Разобраны вопросы и трудности
- Проведен public code review
- Участники отвечают на вопросы
Доступ к данным
- Понятие Connection Pool
- Подключение библиотеки
- Конфигурация
- Тестовые и production профили конфигурации источников данных
- Уровни работы с РСУБД
- Pure JDBC
- Spring JDBC Template
- JPA
- Spring Data JPA codegen
- Обзор JPA: core Entities annotations
- Версионирование и провиженинг схемы БД при изменениях структур данных при развитии приложения
- Подключение библиотеки
- Конфигурация
Practice Iteration
Given
- REST API
- Demo application
- Конфигурация Embedded Derby with file persistence
- Конфигурация Connection pool
- Конфигурация Provisioning library
When
- Произведен рефакторинг приложения на РСУБД для хранения данных
- Реализовано версионирование схемы БД
Then
- Разобраны вопросы и трудности
- Проведен public code review
- Участники отвечают на вопросы
Production-ready REST API
- Версионирование REST API
- Безопасность
- CORS
- CSRF
- Аутентификация и провайдеры
- Авторизация
- Документация на Swagger
- Валидация данных модели
Practice Iteration
Given
- Demo application
- REST API
When
- Произведен рефакторинг приложения до уровня production-ready
- API задокументирован на Swagger
- API протестирован в Swagger UI
Then
- Разобраны вопросы и трудности
- Проведен public code review
- Участники отвечают на вопросы