Закладка интерфейса AngularJS (прямой доступ) - бэкэнд Spring Data Rest
Я начал реализовывать веб-интерфейс для управления сервисом RESTful, обслуживаемым Spring Data Rest
над традиционной реляционной БД. Это сделано с AngularJS
и angular-hal
Библиотека, которую я нашел, очень хорошо вписывается HATEOAS
философия и формализм Spring Data Rest
,
Например, мне просто нужно знать первую конечную точку API ('/'), а затем все мои запросы выполняются через отношения без учета URL-адресов. У меня проблема в том, чтобы иметь возможность прямого доступа к странице, отображающей одну из моих сущностей.
Давайте возьмем пример хранилища контактов. Если я начну с домашней страницы, затем перейду по списку контактов, затем выберу контакт, который я хочу увидеть в деталях, проблем нет.
Но я не могу получить прямой доступ к странице, показывающей детали контакта: ресурс вводится из контроллера списка в контроллер редактирования, и контроллер редактирования не может узнать URL-адрес для запроса, если контроллер списка не сообщает.
Корень проблемы в том, что с Spring Data Rest
субъекты не имеют публичного поля для своих id
(не в JSON), а репозитории не имеют API relation
искать по идентификатору.
Я думал о некоторых решениях, но мне не нравится ни одно из них.
1. Обойти в бэкэнде
- Добавить
Projection
с методомgetId()
для всех объектов, которые должны быть в закладки - Добавьте соответствующий
findById()
в интерфейсе репозитория - Используйте идентификатор в URL внешнего интерфейса в качестве параметра (или пути) и разрешите ресурс, вызвав новое доступное отношение поиска.
- Недостатки: это вынуждает нас вручную переделывать все DTO, автоматически сгенерированные Spring Data Rest, поэтому мы теряем одну из целей фреймворка.
- Вопрос: есть ли способ настроить Spring для автоматического предоставления этих полей id и методов findById?
2. Используйте отношение к себе
- Получите собственный URI объекта с
angular-hal
$href('self')
метод - Используйте его в качестве параметра страницы и разрешите ресурс, вызвав новый
halClient.$get(resourceUri)
в теме - Недостатки: URI должен обрабатываться до и после размещения в URL страницы, чтобы предотвратить ошибки из-за другого "http://" в адресной строке. Я думал о том, чтобы сделать на нем кодировку base64, но это потребляет много времени.
- Недостатки: это раскрывает URL-адрес API для всего мира, и эти данные могут быть критическими и должны оставаться скрытыми (даже если они будут доступны через отладчик, следящий за сетевым трафиком).
3. Забудьте о HATEOAS
- Не беспокойтесь об отношениях и возможности открытия
- Снимает
angular-hal
и просто использовать$resource
с простыми старыми отображениями URL - Недостатки: это идет назад, и кажется, что вы не следуете руководящим принципам...
Итак, я что-то упустил? Какова наилучшая практика в отношении доступа к данным в полной среде RESTFul HATEOAS?
1 ответ
Я нашел exposeIdsFor
методы, позволяющие добавить поле, помеченное @Id в JSON.
@Configuration
public class RepositoryConfiguration extends SpringBootRepositoryRestMvcConfiguration {
/**
* add here the main resources that would need direct access from outside
*/
@Override
protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.exposeIdsFor(Contact.class, User.class);
}
}
Затем я сделал все сущности, которые я хочу, чтобы идентификатор был наследован от общего абстрактного класса.
@MappedSuperclass
public abstract class AbstractEntity {
@Id @GeneratedValue
Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
этот абстрактный класс обслуживается @NoRepositoryBean
хранилище
@NoRepositoryBean
public interface AbstractEntityRepository<T extends AbstractEntity> extends JpaRepository<T, Long> {
@RestResource(rel = "byId")
T findById(@Param("id") Long id);
}
и тогда я могу предоставить и id, и метод byId() для интересующих меня сущностей:
@Entity
public class Contact extends AbstractEntity {
@Column
String name;
@Column
String email;
}
public interface ContactRepository extends AbstractEntityRepository<Contact> {
}
Я думаю, что это делает хорошую работу вокруг и позволяет прямой доступ организаций от клиента по небольшой цене