Reputation: 129
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.
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.
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?
@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:
{
"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.
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.
Upvotes: 0
Views: 132
Reputation: 13556
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.
I am not an expert in Cloud Endpoints, but I run across this architectural problem frequently and solve it in the same way:
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.
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.
Upvotes: 3