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

时间:2021-02-20 23:11:13

I have a Google Cloud Endpoint API which returns a Product object. This product object itself contains another object Brand which is very large (id, name, text, description, image URLs, ...). When getting a list of products I don't need the whole information inside Brand, just the id and title.

我有一个Google Cloud Endpoint API,它返回一个Product对象。此产品对象本身包含另一个非常大的对象Brand(id,name,text,description,image URL,...)。获取产品列表时,我不需要Brand中的所有信息,只需要id和title。

So I tried to factor out Brand to a base class BrandBase which only contains a limited set of properties (only id and title). And inside Product in the public BrandBase getBrand() method I return a BrandBase object.

所以我试图将Brand分解为基类BrandBase,它只包含一组有限的属性(只有id和title)。而在公共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). 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 Endpoints的JSON输出 - 我仍然可以获得整个品牌内容(包括所有文字,说明等)。因此,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.

所以它仍然包含文本和联系人 - 两者都没有在BrandBase类中指定。

Is this a bug or feature of 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.

这是Google Cloud Endpoints的错误或功能吗?或者是否有其他方法可以获得我想要的行为:我只希望在产品中有一个浅薄的品牌对象 - 而不是完整的品牌对象。

1 个解决方案

#1


3  

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

您需要将数据模型与API模型分开。来回传递实体对象仅适用于非常简单的实体对象和非常简单的应用程序。当您需要不同呼叫者的不同对象视图或隐藏某些数据时,是时候考虑单独的DTO了。

For clients that are hard to upgrade (like native apps deployed in the field), you should start with DTOs immediately. This gives you the freedom to refactor your data model as you see fit while carefully controlling API compatibility. 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.

对于难以升级的客户端(如在现场部署的本机应用程序),您应立即从DTO开始。这使您可以*地按照自己的意愿重构数据模型,同时仔细控制API兼容性。是的,这是更多的工作,但它将为您节省重大的麻烦。使用http://projectlombok.org/来摆脱大部分样板。

#1


3  

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

您需要将数据模型与API模型分开。来回传递实体对象仅适用于非常简单的实体对象和非常简单的应用程序。当您需要不同呼叫者的不同对象视图或隐藏某些数据时,是时候考虑单独的DTO了。

For clients that are hard to upgrade (like native apps deployed in the field), you should start with DTOs immediately. This gives you the freedom to refactor your data model as you see fit while carefully controlling API compatibility. 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.

对于难以升级的客户端(如在现场部署的本机应用程序),您应立即从DTO开始。这使您可以*地按照自己的意愿重构数据模型,同时仔细控制API兼容性。是的,这是更多的工作,但它将为您节省重大的麻烦。使用http://projectlombok.org/来摆脱大部分样板。