У меня есть HATEOAS Spring rest API, который подключается к базе данных mysql. У меня нет контроля над схемой базы данных, и она периодически меняется, поэтому я периодически генерирую классы сущностей и обновляю сервис.
У меня три файла на маршрут. Сгенерированный класс сущностей, контроллер и файл репозитория, который использует класс PagingAndSortingRepository
для автоматического обслуживания моих сущностей без особой настройки.
Класс сущности
package hello.models;
import javax.persistence.*;
import java.util.Objects;
@Entity
@Table(name = "animals", schema = "xyz123", catalog = "")
public class AnimalsEntity {
private Integer id;
private String name;
private String description;
@Id
@Column(name = "id", nullable = false)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Basic
@Column(name = "name", nullable = true, length = 80)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Basic
@Column(name = "description", nullable = true, length = 255)
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RoleEntity that = (RoleEntity) o;
return Objects.equals(id, that.id) &&
Objects.equals(name, that.name) &&
Objects.equals(description, that.description);
}
@Override
public int hashCode() {
return Objects.hash(id, name, description);
}
}
Репозиторий класса
package hello.repositories;
@RepositoryRestResource(collectionResourceRel = "animals", path = "animals")
public interface AnimalsRepository extends PagingAndSortingRepository<AnimalEntity, String> {
// Allows /animal/cheetah for example.
AnimalEntity findByName(String name);
// Prevents POST /element and PATCH /element/:id
@Override
@RestResource(exported = false)
public AnimalEntity save(AnimalEntity s);
// Prevents DELETE /element/:id
@Override
@RestResource(exported = false)
public void delete(AnimalEntity t);
}
Класс контроллера
package hello.controllers;
import hello.models.AnimalsEntity;
import hello.repositories.AnimalsRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.RepositoryRestController;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@RepositoryRestController
@RequestMapping("/animals")
class PrinterController {
@Autowired
private AnimalsRepository animalsRepo;
@RequestMapping("/{name}")
public @ResponseBody
List<AnimalsEntity> findAnimal(@PathVariable(value = "name") String name) {
return animalsRepo.findByName(name);
}
}
Я хочу, чтобы мой HATEOAS API обслуживал вещи с параметрами разбивки на страницы / сортировки. В настоящее время они подают ответы как ..
{
"links" : [ {
"rel" : "first",
"href" : "http://localhost:8080/animals?page=0&size=20",
"hreflang" : null,
"media" : null,
"title" : null,
"type" : null,
"deprecation" : null
}, {
"rel" : "self",
"href" : "http://localhost:8080/animals{?page,size,sort}",
"hreflang" : null,
"media" : null,
"title" : null,
"type" : null,
"deprecation" : null
}, {
"rel" : "next",
"href" : "http://localhost:8080/animals?page=1&size=20",
"hreflang" : null,
"media" : null,
"title" : null,
"type" : null,
"deprecation" : null
}, {
"rel" : "last",
"href" : "http://localhost:8080/animals?page=252&size=20",
"hreflang" : null,
"media" : null,
"title" : null,
"type" : null,
"deprecation" : null
}, {
"rel" : "profile",
"href" : "http://localhost:8080/profile/animals",
"hreflang" : null,
"media" : null,
"title" : null,
"type" : null,
"deprecation" : null
}, {
"rel" : "search",
"href" : "http://localhost:8080/animals/search",
"hreflang" : null,
"media" : null,
"title" : null,
"type" : null,
"deprecation" : null
} ],
"content" : [ {
"id" : 1,
"name" : "cheetah",
"description": "xyz
]
},{
"id" : 2,
"name" : "tortise",
"description": "xyz
]
}],
"page" : {
"size" : 20,
"totalElements" : 5049,
"totalPages" : 253,
"number" : 0
}
}
Это потрясающе. Но мне нужны мои приложения javascript для доступа к остальным API, как (GET) /animals/cheetah
.
Обычно я бы изменил схему и установил @Id
для свойства name в классе сущностей, но я не могу этого сделать в этом случае. Я не могу изменить схему базы данных и, в конечном итоге, хочу динамически генерировать эти классы сущностей, чтобы можно было легко изменять схему.
Я понял, что могу переопределить конечную точку и обслуживать ее вручную, но потерял форматирование страниц / HATEOAS.
[
{
"id": 1,
"name": "cheetah",
"description": "xyz"
},
{
"id": 2,
"name": "tortise",
"description": "xyz"
}
]
Как мне выполнить изменение @Id без потери формата JSON или изменения класса сущности?