Перейти к основному содержимому

Создание новых API и представлений в JHipster

· 4 мин. чтения

1. Введение

В этом руководстве мы увидим, как мы можем создать новый API внутри приложения JHipster . Затем мы интегрируем этот API во внешний дисплей.

2. Образец заявления

В этом уроке мы будем использовать простое приложение книжного магазина.

Книжный магазин построен как монолит. Он использует Angular для внешнего интерфейса и имеет единую сущность с именем book со следующими полями:

  • Заголовок
  • Автор
  • Опубликованные данные
  • Цена
  • Количество

JHipster автоматически генерирует API и интерфейсные представления, которые обеспечивают простые операции с книгой : просмотр, создание, редактирование и удаление.

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

Мы сосредоточимся только на API и интерфейсных аспектах покупки. Мы не будем выполнять какую-либо обработку платежей и только минимальную проверку.

3. Весенние изменения загрузки

JHipster предоставляет генератор для создания новых контроллеров . Однако для этого руководства мы вручную создадим API и связанный с ним код .

3.1. Класс ресурсов

Первый шаг — обновить сгенерированный класс BookResource . Мы добавляем новую конечную точку, которую будет вызывать интерфейсный код :

@GetMapping("/books/purchase/{id}")
public ResponseEntity<BookDTO> purchase(@PathVariable Long id) {
Optional<BookDTO> bookDTO = bookService.purchase(id);
return ResponseUtil.wrapOrNotFound(bookDTO);
}

Это создает новую конечную точку API, расположенную по адресу /books/purchase/{id} . Единственным вводом является идентификатор книги , и мы возвращаем BookDTO , который будет отражать новый уровень запасов после покупки.

3.2. Сервисный интерфейс и класс

Теперь нам нужно обновить интерфейс BookService , чтобы включить новый метод покупки :

Optional<BookDTO> purchase(Long id);

Затем нам нужно реализовать новый метод в классе BookServiceImpl :

@Override
public Optional<BookDTO> purchase(Long id) {
Optional<BookDTO> bookDTO = findOne(id);
if (bookDTO.isPresent()) {
int quantity = bookDTO.get().getQuantity();
if (quantity > 0) {
bookDTO.get().setQuantity(quantity - 1);
Book book = bookMapper.toEntity(bookDTO.get());
book = bookRepository.save(book);
return bookDTO;
}
else {
throw new BadRequestAlertException("Book is not in stock", "book", "notinstock");
}
}
return Optional.empty();
}

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

Если он существует, то мы гарантируем, что уровень его запасов больше нуля. В противном случае мы выбрасываем исключение BadRequestAlertException. Хотя это исключение обычно используется только на уровне REST JHipster, мы используем его здесь, чтобы продемонстрировать, как возвращать полезные сообщения об ошибках во внешний интерфейс.

В противном случае, если запас больше нуля, то уменьшаем его на единицу, сохраняем в репозиторий и возвращаем обновленный DTO.

3.3. Конфигурация безопасности

Последнее требуемое изменение находится в классе SecurityConfiguration :

.antMatchers("/api/books/purchase/**").authenticated()

Это гарантирует, что вызовы нашего нового API разрешены только пользователям, прошедшим проверку подлинности.

4. Внешние изменения

Теперь давайте сосредоточимся на внешних изменениях. JHipster создает представление для отображения одной книги, и туда мы добавим нашу новую кнопку покупки .

4.1. Класс обслуживания

Во- первых, нам нужно добавить новый метод в существующий файл book.service.ts . Этот файл уже содержит методы для манипулирования объектами книги, так что это хорошее место для добавления логики для нашего нового API:

purchase(id: number): Observable<EntityResponseType> {
return this.http
.get<IBook>(`${this.resourceUrl}/purchase/${id}`, { observe: 'response' })
.pipe(map((res: EntityResponseType) => this.convertDateFromServer(res)));
}

4.2. Составная часть

Затем нам нужно обновить код компонента в book.component.ts . Мы создадим функцию, которая вызывает новый метод в книжном сервисе Angular, а затем прослушивает ответ от сервера:

purchase(id: number) {
this.bookService.purchase(id).subscribe(
(res: HttpResponse<IBook>) => {
this.book = res.body;
},
(res: HttpErrorResponse) => console.log(res.message)
);
}

4.3. Вид

Наконец, мы можем добавить кнопку в представление книги , которая вызывает новый метод покупки в компоненте:

<button type="button"
class="btn btn-primary"
(click)="purchase(book.id)">
<span>Purchase</span>
</button>

На изображении ниже показано обновленное представление интерфейса:

./2cbbf803b8ed00eed9e0d463782bdd39.jpg

Нажатие новой кнопки « Купить » приведет к вызову нашего нового API, и внешний интерфейс автоматически обновится с учетом нового состояния запасов (или отобразит ошибку, если что-то пошло не так).

5. Вывод

В этом руководстве мы увидели, как создавать собственные API в JHipster и интегрировать их во внешний интерфейс.

Мы начали с добавления API и бизнес-логики в Spring Boot. Затем мы изменили интерфейсный код, чтобы использовать новый API и отображать результаты. Приложив небольшие усилия, мы смогли добавить новые функции поверх существующих операций CRUD , которые автоматически генерирует JHipster.

И, как всегда, код доступен на GitHub .