英文:
Best practice when returning from Restful services - returning Java Object vs returning manually constructed JSON
问题
我目前正在开发返回List<ConfidentialData>
的RESTful Web服务。(我将使用ConfidentialData
作为此问题的示例)
假设ConfidentialData
定义如下:
@Getter
@Setter
public class ConfidentialData {
private Integer id; // 唯一标识符
private String data;
private String creationDate;
private String approvalDate;
}
现在,我正在使用Jackson将这个List<ConfidentialData>
转换为JSON,并将其作为Response
发送。
现在,UI中的不同组件需要ConfidentialData
的不同状态。假设我的某个UI页面(称为page1)需要纯粹的ConfidentialData
对象(JSON中没有任何额外的成员),而另一个页面(称为page2)需要带有一些附加成员的ConfidentialData
对象(假设这些成员与ConfidentialData
的某些统计信息有关。这些统计数据实际上不属于ConfidentialData
对象,但当page2请求时,需要将其添加到JSON中)。
我有3种选择:
- 为page1和page2构造单独的领域对象。
- 我担心这个解决方案在可扩展性方面不是很好,因为可能会有更多页面需要稍微不同的
ConfidentialData
组合,这样会使我的领域对象变得庞大。
- 我担心这个解决方案在可扩展性方面不是很好,因为可能会有更多页面需要稍微不同的
- 只保留一个单一的领域对象,并构造JSON - 通过添加特定页面所需的附加成员。
- 我可以看出,这种情况下我需要处理JSON。(但我也知道,存在像GSON这样的复杂库,可以让我的工作变得容易)
- 我可以简单地创建一个单一的领域对象,其中包含page1、page2、page3等所需的一切内容。(并且在需要时,我会继续向这个
ConfidentialData
领域对象添加任何附加成员)- 我非常反对这种方法,因为我们要讨论的机密数据的附加成员不容易计算。在某些情况下,它可能是与
ConfidentialData
相关的某些统计数据,计算这些统计数据将会是计算成本昂贵的。当UI永远不会使用它时(例如在page1的情况下),我不希望我的简单API调用执行所有这些计算。
- 我非常反对这种方法,因为我们要讨论的机密数据的附加成员不容易计算。在某些情况下,它可能是与
我可以看到第一种和第二种方法的明显缺点。
我的问题是,在处理这种情况时,RESTful服务中的良好做法是什么。
为什么不操纵JSON:
- 另外,我不太喜欢使用JSON,因为我们Java的权限过滤器(这是一个拦截器,它拦截来自服务的响应,并根据用户的权限对列表进行一些过滤)将不得不调整
JsonArray
以进行过滤,而不是简单地对List<ConfidentialData>
进行过滤。 - 但考虑到我们有像GSON这样复杂的库,过滤可能会很容易。
- 另外,由于过滤只基于
ConfidentialData#getId()
(并且这永远不会改变),我可以考虑采用基于JSON的方法,目前看来在可扩展性方面很有前途。
我可以看到这是在操作JSON和创建多个领域对象之间的权衡。在业界是否有遵循的标准来处理这种情况呢?
英文:
I'm currently working on restful web services that returns, say a List<ConfidentialData>
. (I'm using this ConfidentialData
as an example for this question)
Suppose that this ConfidentialData
is defined as follows:
@Getter
@Setter
public class ConfidentialData {
private Integer id; // unique-identifier
private String data;
private String creationDate;
private String approvalDate;
}
Now, I'm using jackson which behind the scene converts this List<ConfidentialData>
to JSON and sends it as Response
.
Now, different components in UI requires different state of ConfidentialData
. Let's suppose that one of my UI pages (say page1) require the pure ConfidentialData
object (without any additional members in JSON), and another page (say page2) requires ConfidentialData
object with some additional members (Say these members are related to some statistics of ConfidentialData
. These statistics don't really belong to the ConfidentialData
object, but are to be added when page2 asks for it).
I've 3 options to go about it:
- Construct a separate domain object for page1 and page2.
- I'm afraid that this solution is not very scalable as there can be more page that required slightly different composition of
ConfidentialData
and I'll end up bloating up my domain objects.
- I'm afraid that this solution is not very scalable as there can be more page that required slightly different composition of
- Just keep one single domain object and construct JSON - by adding additional members that are required by specific pages.
- I can see that I'll have to play with JSON in this case. (But I'm also aware of the fact that there exists sophisticated libraries like GSON that will make my life easy)
- I can can simply create one single domain object that will contain everything that's required by page1, page2, page3 and so on. (And I'll keep adding any additional members to this
ConfidentialData
domain object as and when required)- I'm very much opposed to this approach as the additional members that we're talking about with confidential data aren't easy to calculate. In some cases it can be some statistics related to
ConfidentialData
and it'll be computationally expensive to calculate those statistics. I don't want my simple API call to do all this computation, when the UI won't ever use it (eg. in case of page1)
- I'm very much opposed to this approach as the additional members that we're talking about with confidential data aren't easy to calculate. In some cases it can be some statistics related to
I can see obvious drawbacks of both the first and the second approach.
My question here is what is the good practice in terms of restful services to handle such a situation.
Why not manipulate the JSON:
- Also, I'm not very much in favor of using JSON, as our java's permissions-filter (which is an interceptor - which intercepts the response from the services, and does some filtering on the list based on user's permissions) will then have to tweak
JsonArray
for doing the filtering, instead of simply filteringList<ConfidentialData>
. - But given that we've sophisticated libraries like GSON, the filtering can be easy.
- Also, as the filtering is to be done only on the basis of
ConfidentialData#getId()
(and this is never going to change) I can think of going ahead with JSON based approach which at the moment looks promising in terms of scalability.
I can see it as a trade-off between manipulating JSON and creating multiple domain objects. Is there any standard that's followed in industry to handle this kind of situation?
答案1
得分: 0
根据您的服务调用方式,您可以仅填充ConfidentialData
的相应属性,保持其他属性不变。在序列化过程中,您可以省略任何未设置的属性。这可以通过提供序列化库(无论是Jackson还是Gson)的适当元数据来实现。
英文:
Depending on how your service has been called, you can populate only corresponding properties of the ConfidentialData
and leave others intact. During serialization you can omit any unset properties. This can be achieved by supplying appropriate metadata of serialization library, be it Jackson or Gson.
专注分享java语言的经验与见解,让所有开发者获益!
评论