22

I want to expose data from a database as Restful APIs in a Spring(SpringBoot) application. Spring Data Rest appears to be an exact fit for purpose for this activity.

This database is read-only for my application needs. The default provides all the HTTP methods. Is there a configuration that I can use to restrict (in fact prevent) the other methods from being exposed?

Manglu
  • 10,744
  • 12
  • 44
  • 57
  • 4
    The most convenient way would be to use Spring security to block everything other than GET requests. SDR does provide functionality in this area: http://docs.spring.io/spring-data/rest/docs/current/reference/html/#customizing-sdr.hiding-repository-crud-methods however handling at the HTTP level via Spring Security is simpler. – Alan Hay Feb 28 '17 at 10:50

4 Answers4

38

From the Spring docs on Hiding repository CRUD methods:

16.2.3. Hiding repository CRUD methods

If you don’t want to expose a save or delete method on your CrudRepository, you can use the @RestResource(exported = false) setting by overriding the method you want to turn off and placing the annotation on the overriden version. For example, to prevent HTTP users from invoking the delete methods of CrudRepository, override all of them and add the annotation to the overriden methods.

@RepositoryRestResource(path = "people", rel = "people")
interface PersonRepository extends CrudRepository<Person, Long> {

  @Override
  @RestResource(exported = false)
  void delete(Long id);

  @Override
  @RestResource(exported = false)
  void delete(Person entity);
}

It is important that you override both delete methods as the exporter currently uses a somewhat naive algorithm for determing which CRUD method to use in the interest of faster runtime performance. It’s not currently possible to turn off the version of delete which takes an ID but leave exported the version that takes an entity instance. For the time being, you can either export the delete methods or not. If you want turn them off, then just keep in mind you have to annotate both versions with exported = false.

jww
  • 97,681
  • 90
  • 411
  • 885
12

As of early 2018, there is now the ability to only expose repository methods explicitly declared for exposure (DATAREST-1176)

See RepositoryRestConfiguration

A Export false at Type level does not allow overriding with export true at Method level ticket (DATAREST-1034) was opened, but closed as a duplicate of DATAREST-1176. Oliver Gierke stated:

I'll resolve this as fixed against the version of DATAREST-1176 for now but feel free to reopen in case there's anything else you need.

They are not exact duplicates and the functionality described in 1034 would have been more user friendly, but there are at least some options now.

Snekse
  • 15,474
  • 10
  • 62
  • 77
  • Could you please explain how this is possible? I can't find it anywhere. – Hamid Mohayeji Jul 17 '19 at 16:43
  • @HamidMohayeji This may not entirely answer your question, but the `ExposureConfiguration` is probably the most correct way to configure this. *Customizing default exposure* https://docs.spring.io/spring-data/rest/docs/current/reference/html/#customizing-sdr.http-methods.default-exposure * ExposureConfiguration* https://docs.spring.io/spring-data/rest/docs/current/api/org/springframework/data/rest/core/mapping/ExposureConfiguration.html – Snekse Jul 17 '19 at 19:01
  • @HamidMohayeji If the above comment fails, then getting a handle on the `RepositoryRestConfiguration` and setting the `repositoryDetectionStrategy` might be an option. You can search that class for usage of `expose` as well as there are several options for changing default exposure. There may be spring boot properties to adjust these things. – Snekse Jul 17 '19 at 19:13
  • What if you want to to use JpaRepository, will it still work? – arxakoulini Jun 26 '20 at 08:15
  • @nikiforos There's one way to find out – Snekse Jun 27 '20 at 14:20
2

Since Spring Data REST 3.1, we can configure exposure per HTTP method. I used the following snippet to disable exposure of PUT, PATCH, POST and DELETE methods for items and collections:

@Component
public class SpringDataRestCustomization implements RepositoryRestConfigurer {

    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {
        ExposureConfiguration exposureConfiguration = config.getExposureConfiguration();
        exposureConfiguration.withItemExposure((metadata, httpMethods) -> httpMethods.disable(HttpMethod.PUT)
                        .disable(HttpMethod.PATCH).disable(HttpMethod.POST).disable(HttpMethod.DELETE))
                .withCollectionExposure((metadata, httpMethods) -> httpMethods.disable(HttpMethod.PUT)
                        .disable(HttpMethod.PATCH).disable(HttpMethod.POST).disable(HttpMethod.DELETE));
    }
}
derwiwie
  • 875
  • 10
  • 16
1

By default, Spring boot exposes all methods to REST. You can set that to false.

config.setExposeRepositoryMethodsByDefault(false);

For more information, you can refer org.springframework.data.rest.core.config.RepositoryRestConfiguration.

Sample code snippet to do this:

@Configuration
public class ApplicationRepositoryConfig implements RepositoryRestConfigurer {

    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {
        ..........
        config.setExposeRepositoryMethodsByDefault(false);
    }
}
Mathew Stephen
  • 309
  • 2
  • 7