- IntelliJ IDEA CE или аналоги (OpenIDE, GigaIDE)
- Плагин для работы со Spring проектами Amplicode.
- JDK 21 / JDK 17
- Kotlin
- Postman
- Bruno
PS: Вы можете использовать любую другую IDE, но тогда вам придется самостоятельно разобраться в том как это все работает ^_^ PPS: Вы также можете выбрать сборщик (Gradle/Maven). На данном этапе это не имеет значения
Здесь мы рассмотрим процесс создания простого REST API с использованием фреймворка Spring Boot.
Мы создадим 1 эндпоинт и проведем тестирование его работоспособности через различные инструменты.
-
Открываем IDE и создаем новый проект

По умолчанию сборщик - Maven, так и оставляем, язык Kotlin.
Откроется созданный проект. структура должна быть примерно следующей:

-
Далее откроем файл конфигурации
pom.xml. Нужно будет добавить несколько зависимостей в проект
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>tools.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
</dependency>- Далее запустим приложение (хоть пока ничего нет, мы должны проверить работоспособность). Сделать это можно нажав на зелененькую стрелочку слева от метода main или выполнив команду из терминала
./mvnw spring-boot:runили
./mvnw clean package
java -jar target/*-SNAPSHOT.jarЕсли файл ./mvnw или ./mvnw.cmd отсутствует, то попробуйте выполнить mvn wrapper:wrapper
Если все работает - ОТЛИЧНО!
-
Далее создадим контроллер для первого эндпоинта в пакете
controller.

-
В файле контроллера напишем следующий код:
@RestController
@RequestMapping("/greeting")
class HelloController {
@GetMapping
fun hello(): String {
return "Hello World"
}
}И проверим работу приложения. Запускается по той же схеме, что выше.
После запуска перейдите по ссылке http://localhost:8080/greeting в браузере.
Если в браузере вы увидели Hello World - значит все сделали правильно.
- Далее сделаем косметические улучшения в коде.
Добавим дата-класс в новый пакетdto
data class GreetingMain(
val text: String = "Hello World"
)И теперь будем вместо String возвращать объект этого класса.
@RestController
@RequestMapping("/greeting")
class HelloController {
@GetMapping
fun hello(): GreetingMain {
return GreetingMain()
}
}В данном разделе мы рассмотрим различные технологии для тестирования работоспособности rest api.
curl http://localhost:8080/greetingили для подробного вывода:
curl -v http://localhost:8080/greetingну или более сложные запросы:
# POST с JSON
curl -X POST http://localhost:8080/api/v1/users \
-H "Content-Type: application/json" \
-d '{"name": "John", "email": "john@mail.com"}'
# С авторизацией
curl -H "Authorization: Bearer eyJhbG..." \
http://localhost:8080/api/v1/usersPostman и Bruno — это графические инструменты для отправки HTTP-запросов к API. Они позволяют легко формировать GET,
POST, PUT, DELETE запросы с нужными заголовками и телом, видеть ответ сервера, сохранять запросы в коллекции и использовать переменные окружения.
Главное отличие: Postman хранит коллекции в облаке, а Bruno — в виде текстовых файлов прямо в проекте, что
удобно для Git.
Далее здесь будет продемонстрирован пример работы с Bruno. Для Postman действия аналогичные, за исключением пары
нюансов.
- Для начала создадим рабочее пространство:

- В созданном рабочем пространстве создадим коллекцию запросов (Формат делайте
yaml):

- Далее создадим окружение для рабочего пространства. Тут мы сможем хранить константы (url-ки, токены и тд):

- В переменную окружения запишем url приложения и сохраняем:

- Теперь вы можете использовать переменную окружения для составления запросов:

- Теперь запрос можно выполнить и проверить работоспособность эндпоинта с помощью удобного
нетинтерфейса:

Ну вот допустим вы сделали запрос и запустили его. Но вот вам нужно проверить, что статус код именно такой как вам нужно (не 201, не 300, не 400 и тд). Как тогда поступить? Ведь если вам нужен код ошибки (негативное тестирование), то бруно посчитает, что запрос выполнился некорректно.
Тут на помощь приходят скрипты для запросов. С их помощью можно провести тестирование результатов запроса:
- В окне запроса откроем вкладку
Script->Post Responseи напишем следующий скрипт на проверку статус кода и наличия поля в json ответа:
test("Статус ответа должен быть 200", function() {
expect(res.status).to.equal(200);
});
test("Поле 'text' существует и не является пустым", function() {
const data = res.body;
// Проверяем, что поле существует (не undefined)
expect(data).to.have.property("text");
// Проверяем, что это строка
expect(data.text).to.be.a('string');
// Проверяем, что длина строки больше 0
expect(data.text.length).to.be.greaterThan(0);
});- Затем запустим запрос и увидим вкладку
Testsу результата запроса. Если вы сделали все правильно, то оба теста будут зелеными:

Следующий инструмент для тестирования апи - Connekt. Поставляется он вместе с плагином Amplicode и работает на kotlin. Чтобы создать тест-скрипт, сделаем новую директорию в репозитории и назовем ее .requests, там средствами IDE создадим connekt-скрипт. По-умолчанию там уже содержится примерный код. Если код подсвечивается красным, перезагрузите IDE, обычно это помогает.
- Для начала удалим примерный код и напишем следующий для тестирования нашего эндпоинта:
GET("http://localhost:8080/greeting") {
accept("application/json")
} then {
Assertions.assertThat(code).isEqualTo(200)
}- Каждый раз писать url неудобно, поэтому тут как и в Postman/Bruno есть механизм окружений. Чтобы создать окружение, нажмем
Create environment^-^

- В созданном файле добавим переменную окружения:
{
"local": {
"baseUrl": "http://localhost:8080"
}
}- Теперь можно использовать переменную окружения в скрипте:
val baseUrl: String by env
val path = "greeting"
GET("$baseUrl/$path") {
accept("application/json")
} then {
Assertions.assertThat(code).isEqualTo(200)
}Этот пакет нужен для быстрой сборки уже запущенного приложения Spring Boot при изменениях исходников.
Для начала нужно добавить DevTools в проект. Нужный код для вставки в конфиг сборщика можно найти по ссылке. Ну или:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>Если вы не используете Intellij IDEA UE, то само по себе у вас пересобираться ничего не будет.
Есть множество различиных способов "подсунуть" изменения спрингу. Суть в том, чтобы отслеживать изменения исходников и перекомпилировать нужные файлы, тогда DevTools их увидит и перезапустит приложение.
- Наиболее простой вариант - через связку
findиexec:
find src/main -type f \( -name "*.kt" -o -name "*.java" -o -name "*.properties" -o -name "*.yml" -o -name "*.yaml" -o -name "*.xml" \) \
| entr -r ./mvnw -q -DskipTests compile- Если вы используете Windows, первый вариант может не подойти. Тогда воспользуйтесь утилитой
chokidar.
npm install -g chokidar-cli
# ./mvnw - если все таки у вас UNIX-подобная система
chokidar "src/main/**/*.{kt,java,properties,yml,yaml,xml}" -c "./mvnw.cmd -q -DskipTests compile"Запустите какую-то из этих команд в терминале, в корне проекта, а потом и само приложение. Теперь у вас будет Live Reload в вашем Spring Boot проекте.
Используя этот репозиторий в качестве шаблона (то есть склонируйте его себе и потом залейте себе), выполните следующие задания.
- В соответствии со спецификацией, определенной в файле
specs.yaml, добавьте недостающие эндпоинты в контроллер. Обратите внимание, что первый эндпоинт имеет разное поведение в зависимости от наличия параметра запроса. - Проведите тестрование рассмотренными ранее средствами (Bruno, Connekt, Postman (экспортируйте в json)):
- В каждом инструменте проведите тестирование всех эндпоинтов.
- Url храните в переменных среды.
- Сделайте проверку сохранения пользователя (сохраняйте id пользователя после пост запроса, потом отправляйте его)
Файлы, которые уже лежат в репозитории не изменяйте
| Категория | Критерий | Описание | Баллы |
|---|---|---|---|
| Штрафы | Существующие тесты | Если не проходят существующие Unit-тесты (которые были в шаблоне) | -10 |
| 1. API (10 баллов) | Спецификация OpenAPI | Все эндпоинты реализованы строго по файлу specs.yaml (правильные URL, методы, коды ответов, поля JSON). |
4 |
| Логика GET /greeting | Корректно реализовано разделение логики: запрос без параметров возвращает приветствие, запрос с ?id= ищет пользователя. |
4 | |
| Бизнес-логика | Корректная генерация UUID при создании, сохранение в переменную, возврат 404 при отсутствии пользователя. | 2 | |
| 2. Тестирование (9 баллов) | Postman | 1. Коллекция экспортирована в JSON. 2. URL вынесен в переменные окружения. 3. Реализован сценарии. |
3 |
| Bruno | 1. Файлы коллекции присутствуют. 2. URL в переменных окружения. 3. Реализованы сценарии. |
3 | |
| Connekt | 1. Файлы/Конфиг присутствуют. 2. URL в переменных окружения. 3. Реализованы сценарий. |
3 | |
| 3. Оформление (1 балл) | Культура кода | Чистота кода, отсутствие лишних файлов в репозитории (правильный .gitignore), тесты лежат в папке tests/. |
1 |
| ИТОГО | Максимальный балл | 20 |
