crnk-framework
crnk-framework copied to clipboard
Convert an entity object to document, in the document filter
I have a need to convert an entity object to a Document object so it can be returned to user directly, but can not find out the obvious way.
The code I am targeting is like below:
@Component
public class MyDocumentFilter implements DocumentFilter {
...
...
@Override
public Response filter(DocumentFilterContext filterRequestContext, DocumentFilterChain chain) {
...
if (filterRequestContext.getMethod().equals("POST") &&
// other conditions ) {
...
// MyService.handleRequest is legacy code, which I don't want to re-factor it to fit the way
// how DocumentFilter works.
// The method is called as it was, returning a persisted entity object.
MyEntity entity = MyService.handleRequest(...);
// How can I convert entity to a document, so it can be returned as a result?
// Document document = Some_Convert_Method (entity);
// return new Response(document, HttpStatus.OK.value());
}
}
}
The only way I can find (which is ugly), is like below:
ResourceGetController controller = crnkBoot
.getControllerRegistry()
.getControllers()
.stream()
.filter(c -> c instanceof ResourceGetController)
.findFirst()
.get();
JsonPath path =
new ResourcePath(
filterRequestContext.getJsonPath().getRootEntry(),
Arrays.asList(element.getUuid()));
QuerySpec querySpec = new QuerySpec(MyEntity.class, "type-name");
QueryAdapter adapter =
new QuerySpecAdapter(
querySpec,
filterRequestContext.getQueryAdapter().getResourceRegistry(),
filterRequestContext.getQueryAdapter().getQueryContext());
return controller.handleAsync(artifactPath, adapter, null);
You can get an instance of DocumentMapper
(which behind the scenes makes use of ResourceMapper
from CrnkBoot/ModuleRegistry. This gives a Document
object that can easily be translated to JSON with Jackson.
Thanks @remmeier . So following your suggestion, my code would be something like below.
I verified that it works fine.
DocumentMapper mapper = crnkBoot.getDocumentMapper();
QuerySpec querySpec = new QuerySpec(MyEntity.class, "type-name");
QueryAdapter adapter =
new QuerySpecAdapter(
querySpec,
filterRequestContext.getQueryAdapter().getResourceRegistry(),
filterRequestContext.getQueryAdapter().getQueryContext());
Document result = mapper.toDocument( new JsonApiResponse() {{
setEntity(entity);
}}, adapter, crnkBoot.getModuleRegistry().getDocumentMappingConfig()).get();
return new Response(result, HttpStatus.CREATED.value());
But the next question is, what is the correct way to get CrnkBoot instance? I tried auto-wired it in the document filter, but the application does not start, seems like due to some initialization order issue.
Now I had to create a component to extend CrnkBootConfigurer so as to get the instance and remember it.