Search code examples
javaspringspring-mvcspring-bootspring-data-rest

How to customize Spring Data REST to use a multi-segment path for a repository resource?


I'm developing a component based CRUD application using Spring Data JPA and Spring Data REST. I have several components. For example system component has the User model and the UserRepository. Components are differenciated by the package names. like com.example.app.<component_name>

So to make my REST API look cleaner, I need to implement the API URL as below.

host:8080/<component_name>/<model_collection_name>

for example

host:8080/system/users

I did the following in my repository

@RepositoryRestResource(collectionResourceRel = "users", path = "system/users")
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
   ...
}

this generates the following, when I goto http://localhost:8080

{
   "_links": {
   "users": {
   "href": "http://localhost:8080/system/users{?page,size,sort}",
    "templated": true
},
...

But when I goto http://localhost:8080/system/users

It gives an error

Fri May 22 17:56:37 IST 2015 There was an unexpected error (type=Not Found, status=404). No message available

NOTE : If I mapped the path to system-users then it works fine, but when I use a / in the path such as system/users, it breaks and gives the error.


Solution

  • tl;dr

    Not supported.

    Details

    Generally speaking: don't focus on designing URLs. The structure of a URI must not matter to a REST client by definition:

    At no time whatsoever do the server or client software need to know or understand the meaning of a URI -- they merely act as a conduit through which the creator of a resource (a human naming authority) can associate representations with the semantics identified by the URI.

    (from Roy Fielding - Architectural Styles and the Design of Network-based Software Architectures - Section 6.2.4)

    If you follow that criteria, you take care of choosing relation names, design the representations for the resources you expose etc.

    That said, what you're looking for is currently not supported. If you think it's worthwhile adding this feature (I think it's not, due to the argument given above), feel free to open a ticket in our bug tracker.

    It's probably quite tricky to implement due to the way Spring MVC mapping works and especially the combination of mapping of singular path segments and non-singular ones could cause some ambiguities. All of that makes it rather unlikely this request will get followed up on.