Reputation: 3184
Suppose I have Spring Data repository for a User
entity. Then, Spring Data REST produces the following HAL JSON at its base path:
{
"_links": {
"users": {
"href": "http://localhost:8080/users"
}
}
}
I also want my clients to know that they can call http://localhost:8080/users/{id} to get a specific user (e.g., http://localhost:8080/users/25)
How can I configure Spring Data REST to produce this link for all my entities? For example, I would like Spring Data REST to return something like this:
{
"_links": {
"users": {
"href": "http://localhost:8080/users/{id}",
"templated": true
}
}
}
Update
A good example of what I'm trying to achieve is at https://api.github.com/. The API clearly indicates that https://api.github/users/{user}
is part of the API. For example, https://api.github.com/users/odrotbohm is a valid call.
How can I get Spring Data REST to indicate that htts://localhost:8080/users/{id}
is part of my API?
Update 2
Does the CrudRepository
provide a templated link http://localhost:8080/users/{id}
? I don't see that it does. I'm using Javascript Traverson HAL and without this link I cannot traverse to a specific user.
Update 3
Here is a complete sample of the problem (that I also posted on github):
build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.2'
id 'io.spring.dependency-management' version '1.1.2'
}
group = 'com.example'
version = '1.0'
java {
sourceCompatibility = '17'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-rest'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
In com.example package:
TaversonIssueApplication.java
@SpringBootApplication
public class TaversonIssueApplication {
public static void main(String[] args) {
SpringApplication.run(TaversonIssueApplication.class, args);
}
}
User.java
@Entity
@Table(name="`User`")
@Data
public class User {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String name;
}
UserRepository.java
public interface UserRepository extends CrudRepository<User, Long> {
}
In /src/main/resources:
INSERT INTO "user" (name) VALUES ('bob');
INSERT INTO "user" (name) VALUES ('sally');
Once application is started, a request to http://localhost:8080/
results in:
{
"_links" : {
"users" : {
"href" : "http://localhost:8080/users"
},
"profile" : {
"href" : "http://localhost:8080/profile"
}
}
}
From this response, a client has know way of knowing that http://localhost:8080/users/1
is a valid link. A Traverson HAL client cannot follow the link from http://localhost:8080/
to http://localhost:8080/users/1
. This is because no templated link is provided such as ``http://localhost:8080/users/{id}`.
Is there a way for Spring Data REST to provide such a templated link. Could Spring Data REST produce the following in response to http://localhost:8080/
:
{
"_links" : {
"users" : {
"href" : "http://localhost:8080/users/{id}"
},
"profile" : {
"href" : "http://localhost:8080/profile"
}
}
}
Upvotes: 1
Views: 426
Reputation: 60
Just extend the PagingAndSortingRepository
interface. It also provides additional methods for paging & sorting data.
@RepositoryRestResource(collectionResourceRel = "users", path = "users")
public interface UserRepository extends PagingAndSortingRepository<User, Long>, CrudRepository<User, Long> {
}
Please mind the @RepositoryRestResource
annotation. It allows changing the export details like the name of the collection in the JSON response or as well as the base path for the repository.
Please take a look at this official Spring guide
Upvotes: 1