Java 为数据密集型web服务提供细粒度数据

Java 为数据密集型web服务提供细粒度数据,java,design-patterns,Java,Design Patterns,我正在开发一个真正的数据密集型Web服务。 不幸的是,并非所有调用都需要它返回的所有数据,但另一个调用可能需要它返回的所有数据 过于简化的响应可能如下所示: Response : { A, B, C, D : { X : { } y, z } } 答复:{ A. B C D:{ X:{ } Y Z } } 我希望为调用者提供灵活性,以便他们可以从大对象请求特定数据。 我想通过公开枚举并将枚举

我正在开发一个真正的数据密集型Web服务。 不幸的是,并非所有调用都需要它返回的所有数据,但另一个调用可能需要它返回的所有数据

过于简化的响应可能如下所示:

Response : { A, B, C, D : { X : { } y, z } } 答复:{ A. B C D:{ X:{ } Y Z } } 我希望为调用者提供灵活性,以便他们可以从大对象请求特定数据。 我想通过公开枚举并将枚举列表作为输入来实现它。每个枚举映射到响应中的字段

例如,如果调用者只需要A和D,那么他们可以通过传递像ImmutableList.of(GET_ENUM_A,GET_ENUM_D)这样的枚举列表来指定它 在web服务端,我只能计算A和D

问题: 是否有更好的方法获取调用者所需数据的输入(枚举除外)

我想让用户控制更细粒度的数据,例如,他们可以指定需要D的哪一部分。 获取_ENUM_D_X

在服务器端,我正在考虑使用命令模式来实现它,为每个枚举使用一个命令,并且仅当相应的枚举出现在列表中时才执行它

  • 这里我的D将是一个门面
  • 如果请求粒度数据,则不要使用facade,而是使用X命令
我能想到的问题是:

  • 我的命令太多了
  • 如果一个命令是另一个命令的子集,并且两个命令都被请求,那么只执行超集命令(我们需要在代码中这样做)
有没有更好的办法解决这个问题


(注:由于某些用例,我对将其拆分为更小的API不感兴趣)。

如果您使用Jackson序列化对象,您可以利用视图:

基本上,您可以定义一个视图类,然后在序列化要在视图中传递的对象时。例如:

// View definitions:
class Views {
        static interface A { }
        static interface B { }
        static interface C { }
        static class AC implements A, C { }
}

public class Bean {

        @JsonView(Views.A.class) 
        public Object getA() {
          // compute A
        }
        @JsonView(Views.B.class) 
        public Object getB() {
          // compute B
        }
        @JsonView(Views.C.class) 
        public Object getC() {
          // compute C
        }
}
然后,当您要序列化时,可以传入所需的视图:

objectMapper.writeValueUsingView(out, beanInstance, A.class);
如果你想同时得到a和c,你可以使用AC类

objectMapper.writeValueUsingView(out, beanInstance, AC.class);

如果使用Jackson序列化对象,则可以利用视图:

基本上,您可以定义一个视图类,然后在序列化要在视图中传递的对象时。例如:

// View definitions:
class Views {
        static interface A { }
        static interface B { }
        static interface C { }
        static class AC implements A, C { }
}

public class Bean {

        @JsonView(Views.A.class) 
        public Object getA() {
          // compute A
        }
        @JsonView(Views.B.class) 
        public Object getB() {
          // compute B
        }
        @JsonView(Views.C.class) 
        public Object getC() {
          // compute C
        }
}
然后,当您要序列化时,可以传入所需的视图:

objectMapper.writeValueUsingView(out, beanInstance, A.class);
如果你想同时得到a和c,你可以使用AC类

objectMapper.writeValueUsingView(out, beanInstance, AC.class);

我也不想做额外的处理,目的不仅是减少通过有线传输的字节数,而且也不做不必要的计算。您可以将这些注释放在getter上,fieldsIt并不是一个真正的REST Web服务,但我仍然愿意接受您的建议,因为我可以在内部实现类似的概念。但我仍然无法弄清楚,它将如何适应更大的图景。我也不想做额外的处理,目的不仅是减少通过有线传输的字节,而且也不做不必要的计算。你可以将这些注释放在getter上,fieldsIt也不是真正的REST Web服务,但我仍然愿意接受你们的建议,因为我可以在内部实现类似的概念。但我仍然无法弄清楚,它将如何适应更大的图景。枚举的问题是,如果在D对象中添加一个字段W,则需要添加一个枚举来反映这一点。为什么不让客户选择阅读内容?i、 他可能会使用只包含a和D.X字段的POJO来反序列化接收到的JSON。为了澄清,它不是REST Web服务,输入和输出都是强类型的。因为我可以进行任何深度,根->D->X->,我想让它也使用复合模式实现,但是我想为它实现一个通用的解决方案,我可以很容易地扩展到其他API。枚举的问题是,如果向D对象添加一个字段W,那么需要添加一个枚举来反映这一点。为什么不让客户选择阅读内容?i、 他可能会使用只包含a和D.X字段的POJO来反序列化接收到的JSON。为了澄清,它不是REST Web服务,输入和输出都是强类型的。因为我可以进行任何深度,根->D->X->,我想让它也使用复合模式实现,但是我想为它实现一个通用的解决方案,我可以很容易地扩展到其他API。