spring-projects / spring-projects/spring-data-rest

Use isAssignableFrom() in RepositoryRestConfiguration to check the exposition of ids [DATAREST-406]

Open
#783 0 comments 0 reactions 1 assignee View on GitHub

@odrotbohm is already working on this.

Since Dec 31, 2020.

type: enhancement
Dominant language
Java
Stars
958
Forks
568
PR merge metrics
No merged PRs in 30d

Description

Jérôme Sengel opened DATAREST-406 and commented

Hi,

Right now when you use Spring Data Rest and you want to expose ids in your JSON you can configure your own RepositoryRestMvcConfiguration like so :

@Configuration
@Import(RepositoryRestMvcConfiguration.class)
public class MyRepositoryRestMvcConfiguration extends RepositoryRestMvcConfiguration {

	@Override
	protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
		config.exposeIdsFor(MyEntity.class);
	}
}

And it does work like a charm. However I was wondering : what are we supposed to do when we have a lot of entities and we want to expose all of them ? Since I already had an AbstractEntity annoted with @MappedSuperclass for some generic attributes I tried this :

@Configuration
@Import(RepositoryRestMvcConfiguration.class)
public class MyRepositoryRestMvcConfiguration extends RepositoryRestMvcConfiguration {

	@Override
	protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
		config.exposeIdsFor(AbstractEntity.class);
	}
}

But it can't work because at the moment the method isIdExposedFor(Class<?> domainType) in RepositoryRestConfiguration is written like this :

public boolean isIdExposedFor(Class<?> domainType) {
    return exposeIdsFor.contains(domainType);
}

Since contains(Object o) works with equals(Object obj), the only solution is to register each entity manually. Is it somehow intended to discourage this kind of use or do you think it could be improved ? Right now the only solution I can think of would need to modify isIdExposedFor(Class<?> domainType) and use something like isAssignableFrom(Class<?> cls) instead of contains(Object o).

This is what I ended with and it's working so far :

@Configuration
@Import(RepositoryRestMvcConfiguration.class)
public class MyRepositoryRestMvcConfiguration extends RepositoryRestMvcConfiguration {

	@Bean
	@Override
	public RepositoryRestConfiguration config() {
		RepositoryRestConfiguration config = new MyRepositoryRestConfiguration();
		configureRepositoryRestConfiguration(config);
		return config;
	}

	@Override
	protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
		config.exposeIdsFor(AbstractEntity.class);
	}
}
public class MyRepositoryRestConfiguration extends RepositoryRestConfiguration {

	private List<Class<?>> exposeIdsFor = new ArrayList<Class<?>>();

	@Override
	public boolean isIdExposedFor(Class<?> domainType) {
		for (Class<?> clazz : exposeIdsFor) {
			if (clazz.isAssignableFrom(domainType)) {
				return true;
			}
		}
		return false;
	}

	@Override
	public RepositoryRestConfiguration exposeIdsFor(Class<?>... domainTypes) {
		Collections.addAll(exposeIdsFor, domainTypes);
		return this;
	}
}

Do you think it could be interesting for a pull request or should it stay as an exotic override ? About the performance I didn't notice any difference but again I'm working on a small project so I may lack some perspective.

Thanks in advance for your feedback


1 votes, 2 watchers

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.