【问题标题】:Java Rest API - resource/data separation with JPAJava Rest API - 使用 JPA 分离资源/数据
【发布时间】:2016-11-30 10:24:43
【问题描述】:

我目前正在使用 Java-EE/Jax-RS/JPA 构建一个 rest-api。 我已经有一个工作数据库 + 数据库模型,并使用 eclipse 选项从现有表创建 jpa-entities。 我已经创建了一些基本服务,现在我很好奇使用 jpa-associations 是否对构建 rest-api 有意义,因为它有时会导致大量数据暴露。我也不确定在哪里分离暴露的数据。

例如:

table "FOLDER" has an id, name
table "FOLDER_ITEM" has an id, folder_id (fk), item_id (fk)
table "ITEM" has an id, name, itemprop_id(fk)
table "ITEM_PROP" has an id, valueA, valueB, valueC

调用 /folders/1 当前输出:

{
  "id": 1,
  "name": "Folder1",
  "items": [
    {
      "id": 1,
      "name": "pencil",
      "item_prop": {
        "id": "1",
        "valueA": "example",
        "valueB": "example",
        "valueC": "example"
      }
    },...]
}

如果有很多项目连接到一个文件夹,这会增加很多数据。

所以我认为通过创建一个服务 /items/{id} 来分离数据可能更简单、更清晰,这一次只能给我一个项目。 但在这种情况下,我还必须创建一个服务来获取文件夹中的项目。例如 /items/?withFolderId=1 甚至 /folders/1/items。我看到以下选项:

1) 使用 jpa-associations 但将项目列表(在文件夹类中)标记为 json-ignored for /folders/1 并在调用 时强制输出项目/folders/1/items.

2) 自己编写查询

如果是后者,我会问自己“我为什么还要使用 jpa?”

虽然对此感到困惑,但我可能还不得不说我所有的表都有一个用户 ID 的外键。 所以我通常只想通过创建服务 /users/1/folders 来获取特定用户(当前登录的用户)的文件夹,此时我将在哪里分离数据? 我可以从 /users/ 端点为我的整个客户端提供服务,这会导致与上述相同的问题。现在我们可以肯定地谈论大量数据暴露,这取决于用户拥有多少文件夹以及文件夹包含多少项目。

{
  "id":1
  "name":"testuser"
  "password":"PW"
  "folders":
    [{
      "id": 1,
      "name": "Folder1",
      "items": [
        {
          "id": 1,
          "name": "pencil",
          "item_prop": {
            "id": "1",
            "valueA": "example",
            "valueB": "example",
            "valueC": "example"
          }
        },....]
    },....]
}

我觉得我在这个问题上分散了很多注意力。有什么解决这个问题的建议或常用方法吗?

【问题讨论】:

    标签: java rest jpa jakarta-ee jax-rs


    【解决方案1】:

    如果您使用的是 jackson 库,那么您可以提及 @JsonIgnore 以避免 json 响应。以下示例代码。

    @Entity
    @Table(name="address")
    @EqualsAndHashCode(exclude={"id","companies","clientDetails"})
    @Getter
    @Setter
    @NoArgsConstructor
    @ToString(exclude = {"companies","clientDetails"})
    @JsonIgnoreProperties(ignoreUnknown = true)
    public class Address implements Serializable {
    private static final long serialVersionUID = 1L;
    
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(unique=true, nullable=false)
    private Integer id;
    
    @Column(name="address_line1")
    private String addressLine1;
    
    @Column(name="address_line2")
    private String addressLine2;
    
    @Column
    private String city;
    
    @Column
    private String country;
    
    @Column(name="phone_no")
    private String phoneNo;
    
    @Column(name="postal_code")
    private String postalCode;
    
    @Column
    private String state;
    
    //bi-directional many-to-one association to ClientDetail
    @OneToMany(mappedBy="addressBean",fetch=FetchType.LAZY)
    @JsonIgnore
    private Set<ClientDetail> clientDetails;
    
    //bi-directional many-to-one association to Company
    @OneToMany(mappedBy="address", fetch=FetchType.LAZY)
    @JsonIgnore
    private Set<Company> companies;
    }
    

    【讨论】:

    • 感谢您指出这一点 :) 我只是在过去几个小时内自己解决了这个问题。剩下的唯一问题是在哪里分离数据,但我想这因应用程序而异。
    猜你喜欢
    • 2020-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多