When to use @RestController vs @RepositoryRestResource
Asked Answered
F

4

98

I have been looking at various examples of how to use Spring with REST. Our end target is a Spring HATEOAS/HAL setup

I have seen two distinct methods for rendering REST within Spring

  1. Via @RestController within a Controller

  2. Via @RepositoryRestResource within a Repository

The thing I am struggling to find is why would you use one over the other. When trying to implement HAL which is best?

Our database backend is Neo4j.

Firecracker answered 2/4, 2014 at 23:8 Comment(0)
A
73

Ok, so the short story is that you want to use the @RepositoryRestResource since this creates a HATEOAS service with Spring JPA.

As you can see here adding this annotation and linking it to your Pojo you have a fully functional HATEOAS service without having to implement the repository method or the REST service methods

If you add the @RestController then you have to implement each method that you want to expose on your own and also it does not export this to a HATEOAS format.

Artur answered 20/4, 2014 at 13:46 Comment(3)
By default, Spring Data REST will export ALL top-level, public interface repositories. You only need @RepositoryRestResource to either NOT export an interface, or to alter the details of the endpoint.Monody
If you use RestController with Spring Data REST, you will sidestep EVERYTHING Spring Data REST provides. To code a custom Spring MVC controller that uses Spring data REST's message converters, etc., look into BasePathAwareController.Monody
I don't think the accepted answer is correct @Monody has the better answer.Sulphurbottom
C
42

There is a third (and fourth) option that you have not outlined, which is to use either @BasePathAwareController or @RepositoryRestController, depending on whether you are performing entity-specific actions or not.

@RepositoryRestResource is used to set options on the public Repository interface - it will automatically create endpoints as appropriate based on the type of Repository that is being extended (i.e. CrudRepository/PagingAndSortingRepository/etc).

@BasePathAwareController and @RepositoryRestController are used when you want to manually create endpoints, but want to use the Spring Data REST configurations that you have set up.

If you use @RestController, you will create a parallel set of endpoints with different configuration options - i.e. a different message converter, different error handlers, etc - but they will happily coexist (and probably cause confusion).

Specific documentation can be found here.

Clougher answered 10/11, 2015 at 18:23 Comment(1)
I think this is no longer true. If a @RestController uses the same path as a @RepositoryRestResource, the repository endpoints won't be created.Fetter
A
23

Well, above answers are correct in their context still I am giving you practical example.

In many scenarios as a part of API we need to provide endpoints for searching an entity based on certain criteria. Now using JPA you don't have to even write queries, just make an interface and methods with specific nomenclature of Spring-JPA. To expose such APIs you will make Service layer which would simply call these repository methods and finally Controllers which will expose endpoints by calling Service layer.

What Spring did here, allow you to expose these endpoints from such interfaces (repositories) which are generally GET calls to search entity and in background generates necessary files to create final endpoints. So if you are using @RepositoryRestResource then there is no need to make Service/Controller layer.

On the other hand @RestController is a controller that specifically deals with json data and rest work as a controller. In short @Controller + @ResponseBody = @RestController.

Hope this helps.

See my working example and blog for the same:
http://sv-technical.blogspot.com/2015/11/spring-boot-and-repositoryrestresource.html
https://github.com/svermaji/Spring-boot-with-hibernate-no-controller

Algoid answered 3/12, 2015 at 8:41 Comment(1)
I can see people going to my blog, if this solution works please up vote.Algoid
S
11

@RepositoryRestController override default generated Spring Data REST controllers from exposed repository.

To take advantage of Spring Data REST’s settings, message converters, exception handling, and more, use the @RepositoryRestController annotation instead of a standard Spring MVC @Controller or @RestController

E.g this controllers use spring.data.rest.basePath Spring Boot setting as base path for routing.

See Overriding Spring Data REST Response Handlers.

Be aware of adding @ResponseBody as it is missed in @RepositoryRestController

If you not exposed repository (marked as @RepositoryRestResource(exported = false)), use @BasePathAwareController annotation instead

Also be aware of bags

ControllerLinkBuilder does not take Spring Data REST's base path into account and @RequestMapping shouldn't be used on class/type level

and

Base path doesn't show up in HAL

Workaround to fix link: https://mcmap.net/q/218750/-base-path-doesn-39-t-appear-in-resourceprocessor-custom-links

UPDATE: at last I prefer not to use @RepositoryRestController due to lot of workarounds.

Songwriter answered 7/8, 2018 at 14:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.