Java example to fetch tridion content service PCA graphql response.

- Implementation which is available is built on spring-boot framework, I am gonna put only relative information on graphql and java client.


I have prepared one class which is having few example of tridion pca graphql queries using java,

QueryService.java
@Service
public class QueryService {

final PCAClientProvider pcaClientProvider;

public QueryService(PCAClientProvider pcaClientProvider) {
this.pcaClientProvider = pcaClientProvider;
}

protected ApiClient getPcaClient() {
ApiClient pcaClient = this.pcaClientProvider.getClient();
pcaClient.setDefaultModelType(DataModelType.R2);
pcaClient.setDefaultContentType(ContentType.MODEL);
pcaClient.setModelServiceLinkRenderingType(ModelServiceLinkRendering.RELATIVE);
pcaClient.setTcdlLinkRenderingType(TcdlLinkRendering.RELATIVE);
return pcaClient;
}

protected CustomApiClient getCustomPcaClient() {
CustomApiClient pcaClient = this.pcaClientProvider.getCustomClient();
pcaClient.setDefaultModelType(DataModelType.R2);
pcaClient.setDefaultContentType(ContentType.MODEL);
pcaClient.setModelServiceLinkRenderingType(ModelServiceLinkRendering.RELATIVE);
pcaClient.setTcdlLinkRenderingType(TcdlLinkRendering.RELATIVE);
return pcaClient;
}

public Publication getPublicationTitle(int pubId) {
return getPcaClient().getPublication(ContentNamespace.Sites, pubId, "", null);
}

public Page getPage(int publicationId, int pageId) {
return getPcaClient().getPage(ContentNamespace.Sites, publicationId, pageId, "", ContentIncludeMode.INCLUDE_DATA, null);
}

public PublicationConnection getAllPublications() {
Pagination pagination = new Pagination();
pagination.first = 0;
pagination.after = "";
return getPcaClient().getPublications(ContentNamespace.Sites, pagination, null, "", null);
}

public ComponentPresentation getComponentPresentations(int publicationId, int componentId, int templateId) {
return getPcaClient().getComponentPresentation(ContentNamespace.Sites, publicationId, componentId, templateId, "", ContentIncludeMode.INCLUDE_DATA, null);
}

public BinaryComponent getBinaryComponent(int publicationId, int binaryId) {
return getPcaClient().getBinaryComponent(ContentNamespace.Sites, publicationId, binaryId, "", null);
}

public ComponentPresentationConnection getComponentPresentations(int publicationId) {
Pagination pagination = new Pagination();
pagination.first = 0;
pagination.after = "";
InputComponentPresentationFilter inputComponentPresentationFilter = new InputComponentPresentationFilter();
InputSortParam sortParam = new InputSortParam();
sortParam.setOrder(SortOrderType.Descending);
return getPcaClient().getComponentPresentations(ContentNamespace.Sites, publicationId, inputComponentPresentationFilter,
sortParam, pagination, "", ContentIncludeMode.INCLUDE_DATA, null);
}

public String resolveComponentLink(int publicationId, int targetComponentId, int sourcePageId, int excludeComponentTemplateId, boolean renderRelativeLink) {
return getPcaClient().resolveComponentLink(ContentNamespace.Sites, publicationId, targetComponentId, sourcePageId, excludeComponentTemplateId, renderRelativeLink);
}

public JsonNode getCategories(int publicationId) {
return getCustomPcaClient().getCategories(ContentNamespace.Sites, publicationId);
}
}

for class PCAClientProvider we can take a reference from dxa github repo
https://github.com/RWS/dxa-web-application-java/blob/6e475a85a52d7b8190572662674b43c0d3056fba/dxa-framework/dxa-tridion-common/src/main/java/com/sdl/dxa/tridion/pcaclient/DefaultApiClientProvider.java
we need to have following dependency in the project in order to get PCAClient references.
<dependency>
    <groupId>com.sdl.web.pca</groupId>
    <artifactId>pca-client</artifactId>
    <version>2.2.16</version>
</dependency>


to understand QueryService we can also refer following junit test class
@SpringBootTest
public class QueryServiceTest {

@Autowired
QueryService queryService;

@Test
public void fetchAllPublication() {
PublicationConnection allPublications = queryService.getAllPublications();
assertThat(allPublications, is(notNullValue()));
System.out.printf("total number of web publications are: %d%n", allPublications.getEdges().size());
}

@Test
public void fetchAllCategories() {
int publicationId = 25;
JsonNode categories = queryService.getCategories(publicationId);
assertThat(categories, is(notNullValue()));
System.out.printf("published categories in publication %d%n are: %s%n", publicationId, categories.toPrettyString());
}

@Test
public void fetchBinaryComponent() {
BinaryComponent binaryComponent = queryService.getBinaryComponent(25, 1580);
assertThat(binaryComponent, is(notNullValue()));
System.out.printf("Binary Component id is %s: ", binaryComponent.getId());
}
}

we can also write our own ApiClient in order to get response based on custom query or criteria
for example
public class CustomApiClient extends DefaultApiClient {

private static final Logger LOG = LoggerFactory.getLogger(CustomApiClient.class);
private static final ObjectMapper MAPPER = new ObjectMapper();
private final GraphQLClient graphQLClient;
private final int requestTimeout;

public CustomApiClient(GraphQLClient graphQLClient, int requestTimeout) {
super(graphQLClient, requestTimeout);
this.graphQLClient = graphQLClient;
this.requestTimeout = (int) TimeUnit.MILLISECONDS.toMillis(requestTimeout);
}

public JsonNode getCategories(ContentNamespace ns, int publicationId) {
GraphQLRequest graphQLRequest = (new PCARequestBuilder()).withQuery("AllCategories").withNamespace(ns).withPublicationId(publicationId).withTimeout(this.requestTimeout).build();
Class<JsonNode> clazz = JsonNode.class;
String path = "/data/categories";
return getResultForRequest(graphQLRequest, clazz, path);
}

private <T> T getResultForRequest(GraphQLRequest request, Class<T> clazz, String path) throws ApiClientException {
JsonNode result = getJsonResult(request, path);
try {
return MAPPER.treeToValue(result, clazz);
} catch (JsonProcessingException e) {
throw new ApiClientException("Unable map result to " + clazz.getName() + ": " + result.toString(), e);
}
}

private JsonNode getJsonResult(GraphQLRequest request, String path) throws ApiClientException {
int attempt = 3;
UnauthorizedException[] exception = new UnauthorizedException[1];
while (attempt > 0) {
try {
attempt--;
return getJsonResultInternal(request, path);
} catch (UnauthorizedException ex) {
if (exception[0] == null) exception[0] = ex;
LOG.error("Could not perform query on " + path);
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
throw new ApiClientException("Could not perform query " + request + " after 3 attempts", exception[0]);
}

private JsonNode getJsonResultInternal(GraphQLRequest request, String path) throws ApiClientException, UnauthorizedException {
try {
String resultString = this.graphQLClient.execute(request);
JsonNode resultJson = MAPPER.readTree(resultString);
return resultJson.at(path);
} catch (GraphQLClientException e) {
throw new ApiClientException("Unable to execute query: " + request, e);
} catch (IOException e) {
throw new ApiClientException("Unable to deserialize result for query " + request, e);
}
}
}

Comments