How to mix Spring Data Repositories and Spring Rest Controllers
Asked Answered
P

1

14

Currently I am exposing a few Spring Data Repositories as RESTful services by annotating them with @RepositoryRestResource like this:

@RepositoryRestResource(collectionResourceRel = "thing1", path = "thing1")
public interface Thing1Repository extends PagingAndSortingRepository<Thing1, String> {}

@RepositoryRestResource(collectionResourceRel = "thing2", path = "thing2")
public interface Thing2Repository extends CrudRepository<Thing2, String> {}

This all works great. When you hit my first endpoint is also shows all the Spring Data Repositories I have exposed, like this:

{
   _links: {
      thing1: {
         href: "http://localhost:8080/thing1{?page,size,sort}",
         templated: true
      },
      thing2: {
         href: "http://localhost:8080/thing2"
      }
   }
}

Now I have some endpoints I want to expose that cannot be represented by Spring Data Repositories, so I am using a RestController.

Here is a simple example:

@RestController
@ExposesResourceFor(Thing3.class)
@RequestMapping("/thing3")
public class Thing3Controller {

  @Autowired 
  EntityLinks entityLinks;

  @Autowired 
  Thing3DAO thing3DAO;

  //just assume Thing3.class extends ResourceSupport. I know this is wrong, but it makes the example shorter  
  @RequestMapping(value = "/{id}", produces = "application/json")
  Thing3 thing3(@PathVariable("id") String id)
  {
      Thing3 thing3 = thing3DAO.findOne(id);         

      Link link = entityLinks.linkToSingleResource(Thing3.class, id);
      thing3.add(link);

      return thing3;
  }
}

Now if I run this app and go to:

http://localhost:8080/thing3/{id} 

I do get a JSON representation of the Thing3 with a link to itself, that works as expected.

What I want to figure out how to do is have the first endpoint also describe this controller. I basically want this:

{
   _links: {
      thing1: {
         href: "http://localhost:8080/thing1{?page,size,sort}",
         templated: true
      },
      thing2: {
         href: "http://localhost:8080/thing2"
      },
      thing3: {
         href: "http://localhost:8080/thing3"
      }
   }
}

What do I need to do to get my base endpoint to have a link to this controller?

Perfumery answered 9/12, 2014 at 20:8 Comment(2)
possible duplicate of Custom response for root request int the Spring REST HATEOAS with both RepositoryRestResource-s and regular controllersDevonian
how did you get to have @RestController work with spring-hateoas ? Also, I am trying to understand where does the thing3.add method from. How do you manager for a collection of entities ?Hohenlohe
E
13

You could override RepositoryLinkResource, and add a resource pointing to your thing3:

resource.add(ControllerLinkBuilder.linkTo(Thing3Controller.class).withRel("thing3"));

Check this question: Custom response for root request int the Spring REST HATEOAS with both RepositoryRestResource-s and regular controllers

Euphroe answered 9/12, 2014 at 20:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.