简体   繁体   English

返回的JSON对象不尊重继承吗?

[英]Returned JSON object does not respect inheritance?

I have a Google Cloud Endpoint API which returns a Product object. 我有一个Google Cloud Endpoint API,该API返回一个Product对象。 This product object itself contains another object Brand which is very large (id, name, text, description, image URLs, ...). 该产品对象本身包含另一个很大的对象Brand (id,名称,文本,描述,图像URL等)。 When getting a list of products I don't need the whole information inside Brand , just the id and title. 获取产品列表时,我不需要Brand内的全部信息,只需ID和标题即可。

So I tried to factor out Brand to a base class BrandBase which only contains a limited set of properties (only id and title). 因此,我尝试将Brand BrandBase为一个基类BrandBase ,该基类仅包含一组有限的属性(仅id和title)。 And inside Product in the public BrandBase getBrand() method I return a BrandBase object. public BrandBase getBrand()方法的Product内,我返回一个BrandBase对象。

But then looking at the JSON output from Google Cloud Endpoints - I still get the whole Brand content (including all text, description, etc). 但是,然后查看Google Cloud Endpoints的JSON输出-我仍然可以获得完整的Brand内容(包括所有文本,描述等)。 So it looks like Google Cloud Endpoint just looks at the object-type and serializes everything regardless of the specified return type in the class itself? 因此,看起来Google Cloud Endpoint只是查看对象类型并序列化所有内容,而不管类本身中指定的返回类型如何?

@Entity
public class Product {
  @Id
  private Long id;

  @Index
  private Ref<BrandBase> brand;

  public BrandBase getBrand() {
    return brand.get();
  }

  public void setBrand(BrandBase brand) {
    this.brand = Ref.create(brand);
  }
  ...
}

@Entity
public class Brand extends BrandBase {

  @Id
  private Long id;
  @Index
  private String name;
  private String text;
  private String contact;
  ... all getter/setter ...
}

public abstract class BrandBase {
  public abstract Long getId();
  public abstract String getName();
  public abstract void setName(String name);
}

the returned JSON is: 返回的JSON是:

{
   "id": "6298002603900928",
   "title": "magna aliquyam erat, sed",
   "description": "Lorem ipsum dolor sit amet...",
   "brand": {
     "id": "6192449487634432",
     "name": "no",
     "text": "Lorem ipsum dolor sit amet, ...",
     "contact": "Lorem ipsum dolor..."
   }
 }

so it still contains text and contact - both are not specified in the BrandBase class. 因此它仍然包含textcontact -在BrandBase类中均未指定。

Is this a bug or feature of Google Cloud Endpoints? 这是Google Cloud Endpoints的错误或功能吗? Or are there other methods to get my desired behavior: I only want to have a shallow brand object inside the product - not the full brand object. 还是有其他方法来获得我想要的行为:我只想在产品内部放置浅品牌的对象,而不是完整品牌的对象。

This is most certainly not a bug in endpoints, otherwise there would be no way to return polymorphic objects. 这绝对不是端点中的错误,否则将无法返回多态对象。 Furthermore, every JSON serializer in existence works this same way. 此外,现有的每个JSON序列化程序都以相同的方式工作。

I am not an expert in Cloud Endpoints, but I run across this architectural problem frequently and solve it in the same way: 我不是Cloud Endpoints的专家,但是我经常遇到此架构问题,并以相同的方式解决它:

You need to separate your data model from your API model. 您需要将数据模型与API模型分开。 Passing entity objects back and forth only works for very simple entity objects and very simple applications. 来回传递实体对象仅适用于非常简单的实体对象和非常简单的应用程序。 When you need different views of the objects for different callers, or to hide some pieces of data, it's time to think about separate DTOs. 当您为不同的调用者需要不同的对象视图或隐藏一些数据时,该考虑单独的DTO了。

For clients that are hard to upgrade (like native apps deployed in the field), you should start with DTOs immediately. 对于难以升级的客户端(例如在现场部署的本机应用程序),应立即从DTO开始。 This gives you the freedom to refactor your data model as you see fit while carefully controlling API compatibility. 这使您可以自由地重构您认为合适的数据模型,同时仔细控制API兼容性。 Yes, it's more work, but it will save you major headaches down the road. 是的,这需要更多工作,但是它将为您省去很多麻烦。 Use http://projectlombok.org/ to get rid of most of the boilerplate. 使用http://projectlombok.org/摆脱大部分样板。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM