Optimized resolve - gkresic/commons-fields GitHub Wiki
Resolving object with requested graph is straightforward, but what if you have to perform some actions on it which will require access to attributes original caller didn't request (for example, to perform access control)? As described earlier, default approach would be to first resolve object with graph caller requested and then to let algorithms down the execution path to extend such object with any additional attributes they require.
However, is cases when we know exactly what processing on resolved object will be required down the execution path, we can expand graph that should be resolved with all additional attributes we know we'll need later and by doing that save us some roundtrips to backing storage.
In any case (either one get
+ many extend
s or only one "fat" get
), don't forget to strip any attributes caller
didn't request using intersect
.
For example, consider following JAX-RS endpoint that performs access control check on resolved object before returning it:
@GET
@Produces(MediaType.APPLICATION_JSON)
public Foo get(@QueryParam("id") String id, @QueryParam("@fields") FieldGraph<Foo.Field> graph) {
// build graph which is union of requested graph and one needed for access control
FieldGraph<Foo.Field> graphToResolve = FieldGraph.Builder.of(graph) // start building on requested graph
.add(FooGate.Graph) // extend with graph needed for access control
.build();
// resolve object with extended graph
Foo foo = fooService.get(id, graphToResolve);
// perform checks
FooGate.checkRead(foo);
// strip resolved objects only to attributes requested
foo.intersect(graph);
// finally, return object as API response
return foo;
}