2017-07-15 6 views
1

Je suis en train de concevoir une API utilisant Spring boot pour un backend de réseau social. Mon modèle actuel ressemble à ceci:Conception de DTO à partir d'un modèle pour une API

public class User { 

    private long id; 
    private String handle; 
    private String name; 
    private List<User> followers; 
    private List<User> following; 

    // Getters setters etc 

Maintenant, j'ai créé DTO qui ressemble étroitement à la structure ci-dessus. Mon problème est que parfois je veux retourner exactement ce qui est au-dessus (ce qui est bien) mais parfois, je ne le veux pas.

Par exemple quand quelqu'un est seulement intéressé à trouver les adeptes de l'utilisateur, je ne veux pas inclure disciples et suivants (je suis simplement intéressé par id, handle et name donc calculer followers et following pour tous les utilisateurs seraient un incroyable gaspillage de ressources).

Dans mon implémentation actuelle, ces champs sont retournés avec des valeurs null, ce qui n'est pas une bonne idée, selon moi. Devrais-je créer un DTO distinct sans ces listes avec seulement id, handle et name? Ou y at-il une façon plus élégante de le faire?

+1

Je pense est plus élégant si vous créez une autre couche dans votre api où vous pouvez faire une demande à l'utilisateur par identifiant pour obtenir uniquement des valeurs partielles, sans avoir de sens que si vous obtenir toutes les valeurs seulement pour obtenir une valeur de la réponse DTO. –

Répondre

3

C'est une question controversée. Si vous ne voulez pas créer de dto séparé, il existe plusieurs façons de le faire. Cela dépend de l'approche d'accès aux données que vous allez utiliser:

En utilisant Spring Data JPA, il est possible de renvoyer une entité en projection. Vous avez juste besoin d'ajouter un constructeur supplémentaire à votre entité:

public interface UserRepository extends JpaRepository<User, Long> { 
    @Query("select new User(u.id,u.name) from User u") 
    List<User> findAllUserItems(); 
} 

Ou même en utilisant JPA EntityManger:

public List<User> findAllUserItems() { 
     return entityManager.createQuery("select new User(u.id,u.name) from User u", User.class) 
       .getResultList(); 
    } 

Si vous vous interrogez sur les champs null inutiles et que vous utilisez Jackson, il est possible de configurer ignorer les champs nuls. Pour le printemps Boot:

spring.jackson.default-property-inclusion=non_null 

Ou avec Java config:

@Bean 
    public Jackson2ObjectMapperBuilder objectMapperBuilder() { 
     Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); 
     builder.serializationInclusion(JsonInclude.Include.NON_NULL); 
     return builder; 
    } 

Ou pour ne pas printemps projet Boot:

@Configuration 
@EnableWebMvc 
public class WebConfig extends WebMvcConfigurerAdapter { 
    @Override 
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { 
     converters.add(converter()); 
    } 

    @Bean 
    public HttpMessageConverter converter() { 
     ObjectMapper objectMapper = new ObjectMapper(); 
     objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); 
     return new MappingJackson2HttpMessageConverter(objectMapper); 
    } 
} 

Aussi, si vous allez utiliser session Hibernate. Pour mapper directement DTO vous pouvez utiliser AliasToBeanResultTransformer:

public List<UserDto> findAllUserItems() { 
      return session.createQuery("select u.id as id,u.name as name from User u") 
        .setResultTransformer(Transformers.aliasToBean(UserDto.class)) 
        .list(); 
} 
0

Supposons que vous pouvez essayer comme ceci.

@Entity 
public class User implements Serializable { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private Long id; 

    @ManyToOne 
    private User parent; 

    @OneToMany(mappedBy="parent") 
    private List<User> followers; 

    @OneToMany(mappedBy="parent") 
    private List<User> following; 

    // Getters, Setters etc.... 
} 

Aussi, cette post peut être utile.

+1

Comment cela répond-il exactement à la question? L'OP veut savoir comment il peut empêcher certains champs d'être retournés dans son API REST en utilisant des DTO, alors que votre solution n'est qu'une entité? – g00glen00b