2017-07-15 56 views
1

我正在爲某些社交網絡後端設計使用Spring引導的API。我目前的模型是這樣的:從API模型設計DTO

public class User { 

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

    // Getters setters etc 

現在,我創建了與上述結構非常相似的DTO。我的問題是,有時候我想要返回上面的內容(這很好),但有時候,我不想那樣。

例如,當某人只是在尋找的用戶追隨者感興趣,我不希望包括追隨者和之後(我在idhandlename只是興趣,所以計算所有這些用戶的followersfollowing會令人難以置信的資源浪費)。

在我當前的實現中,這些字段返回值爲null,我認爲這不是一個好主意。我應該創建一個單獨的DTO沒有那些列表只有id,handlename?還是有更優雅的方式來做到這一點?

+1

我覺得是更優雅,如果你創建你的API另一層在那裏你可以提出一個要求用戶通過ID只得到部分值,不具有意義,如果你獲取所有值僅用於從DTO響應中獲取一個值。 –

回答

3

這是一個有爭議的問題。如果你不想創建單獨的dto,有幾種方法可以做到這一點。這取決於您要使用的數據訪問方式:

使用Spring數據JPA可以在投影中返回實體。你只需要一個額外的構造函數添加到您的實體:

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

或者相同的使用JPA EntityManger:

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

如果你想知道不必要的空字段,並且您使用傑克遜,可配置忽略空字段。春季啓動:

spring.jackson.default-property-inclusion=non_null 

或者與Java的配置:

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

或者不春天啓動項目:

@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); 
    } 
} 

另外,如果你打算使用Hibernate的Session。爲了直接映射到DTO你可以使用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

假設你可以這樣嘗試。

@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.... 
} 

此外這個post可能會有所幫助。

+1

這是如何準確回答問題的? OP想知道如何防止某些字段在使用DTO的REST API中返回,而您的解決方案只是一個實體? – g00glen00b