2

I'm currently using Spring Boot to create a REST API with a mongodb backend. Is it possible to only expose certain fields when viewing a specific item, and not a list of items?

For example, when viewing a list of users, to only expose email, name, and id:

GET /{endpoint}/users

{
  "_embedded": {
  "users": [
    {
      "email": "some_email@gmail.com",
      "name": "some name",
      "id": "57420b2a0d31bb6cef4ee8e9"
    }, 
    {
      "email": "some_other_email@gmail.com",
      "name": "some other name",
      "id": "57420f340d31cd8a1f74a84e"
    }
  ]
}

But expose extra fields, e.g. address and gender, when searching for a specific user:

GET /{endpoint}/users/57420f340d31cd8a1f74a84e

{
  "email": "some_other_email@gmail.com",
  "name": "some other name",
  "address": "1234 foo street"
  "gender": "female"
  "id": "57420f340d31cd8a1f74a84e"
}

given a user class:

public class User {

    private String id;
    private String email;
    private String address;
    private String name;
    private String gender;

...
}
Kevin Grant
  • 591
  • 6
  • 15
  • 2
    That is what [Projections and Excerpts](http://docs.spring.io/spring-data/rest/docs/current/reference/html/#projections-excerpts) are for. You can specify what you want and how to display. Assuming that you are using Spring Data REST, that is. If you have your own custom controller, just create a DTO for you need. – M. Deinum May 26 '16 at 06:43
  • Looking over the documentation quickly, it does appear this is exactly what I am looking for. Thank you! – Kevin Grant May 26 '16 at 07:03
  • 1
    @M.Deinum — This should be an answer! :) – Oliver Drotbohm May 26 '16 at 09:42

2 Answers2

8

When using Spring Data REST it has something especially designed for this. There is the notion of Projections and Excerpts with it you can specify what and how you want to return it.

First you would create an interface which would contain only the fields you want.

@Projection(name="personSummary", types={Person.class})
public interface PersonSummary {
    String getEmail();
    String getId();
    String getName();
}

Then on your PersonRepository add this as the default to use (will only apply to methods returning collections!).

@RepositoryRestResource(excerptProjection = PersonSummary.class)
public interface PersonRepository extends CrudRepository<Person, String> {}

Then when doing a query for a collection you will only get the fields as specified in the projection and when obtaining a single instance you will get the full object.

M. Deinum
  • 115,695
  • 22
  • 220
  • 224
1

You have to add @Query annotation on the find method in the repository and specify the fields parameter:

public interface PersonRepository extends MongoRepository<Person, String>

  @Query(value="{ 'firstname' : ?0 }", fields="{ 'firstname' : 1, 'lastname' : 1}")
  List<Person> findByThePersonsFirstname(String firstname);

}

See: http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongodb.repositories.queries.json-based

Marcos Tanaka
  • 3,112
  • 3
  • 25
  • 41