Content Lab 2 - Graphql
Content Lab 2 - Graphql
Content Lab 2 - Graphql
JAM 2021
NOTICES
This information was developed for products and services offered in the USA.
IBM may not offer the products, services, or features discussed in this document in other countries. Consult your local IBM
representative for information on the products and services currently available in your area. Any reference to an IBM product, program,
or service is not intended to state or imply that only that IBM product, program, or service may be used. Any functionally equivalent
product, program, or service that does not infringe any IBM intellectual property right may be used instead. However, it is the user's
responsibility to evaluate and verify the operation of any non-IBM product, program, or service.
IBM may have patents or pending patent applications covering subject matter described in this document. The furnishing of this
document does not grant you any license to these patents. You can send license inquiries, in writing, to:
IBM Director of Licensing
IBM Corporation
North Castle Drive, MD-NC119
Armonk, NY 10504-1785
United States of America
The following paragraph does not apply to the United Kingdom or any other country where such provisions are inconsistent with local
law: INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of express or implied warranties
in certain transactions, therefore, this statement may not apply to you.
This information could include technical inaccuracies or typographical errors. Changes are periodically made to the information herein;
these changes will be incorporated in new editions of the publication. IBM may make improvements and/or changes in the product(s)
and/or the program(s) described in this publication at any time without notice.
Any references in this information to non-IBM websites are provided for convenience only and do not in any manner serve as an
endorsement of those websites. The materials at those websites are not part of the materials for this IBM product and use of those
websites is at your own risk.
IBM may use or distribute any of the information you supply in any way it believes appropriate without incurring any obligation to you.
Information concerning non-IBM products was obtained from the suppliers of those products, their published announcements or other
publicly available sources. IBM has not tested those products and cannot confirm the accuracy of performance, compatibility or any
other claims related to non-IBM products. Questions on the capabilities of non-IBM products should be addressed to the suppliers of
those products.
This information contains examples of data and reports used in daily business operations. To illustrate them as completely as possible,
the examples include the names of individuals, companies, brands, and products. All of these names are fictitious and any similarity to
the names and addresses used by an actual business enterprise is entirely coincidental.
TRADEMARKS
IBM, the IBM logo, and ibm.com are trademarks or registered trademarks of International Business Machines Corp., registered in many
jurisdictions worldwide. Other product and service names might be trademarks of IBM or other companies. A current list of IBM
trademarks is available on the web at “Copyright and trademark information” at www.ibm.com/legal/copytrade.shtml.
Adobe, the Adobe logo, PostScript, and the PostScript logo are either registered trademarks or trademarks of Adobe Systems
Incorporated in the United States, and/or other countries.
Cell Broadband Engine is a trademark of Sony Computer Entertainment, Inc. in the United States, other countries, or both and is used
under license therefrom.
Intel, Intel logo, Intel Inside, Intel Inside logo, Intel Centrino, Intel Centrino logo, Celeron, Intel Xeon, Intel SpeedStep, Itanium, and
Pentium are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States and other countries.
IT Infrastructure Library is a Registered Trade Mark of AXELOS Limited.
ITIL is a Registered Trade Mark of AXELOS Limited.
Java and all Java-based trademarks and logos are trademarks or registered trademarks of Oracle and/or its affiliates.
Linear Tape-Open, LTO, the LTO Logo, Ultrium, and the Ultrium logo are trademarks of HP, IBM Corp. and Quantum in the U.S. and other
countries.
Linux is a registered trademark of Linus Torvalds in the United States, other countries, or both.
Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries,
or both.
UNIX is a registered trademark of The Open Group in the United States and other countries.
© Copyright International Business Machines Corporation 2021.
This document may not be reproduced in whole or in part without the prior written permission of IBM.
US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
1 Introduction.............................................................................................................................. 4
1.1 GraphQL .............................................................................................................................................. 4
1.2 Lab Overview ...................................................................................................................................... 4
1.3 Lab Setup Instructions ....................................................................................................................... 4
2 Exercise: GraphQL Queries ........................................................................................................ 7
2.1 Introduction ........................................................................................................................................ 7
2.2 Exercise Instructions .......................................................................................................................... 7
2.2.1 Domain Queries ........................................................................................................................... 7
2.2.2 Folder Queries ........................................................................................................................... 10
2.2.3 Other Queries ............................................................................................................................. 14
2.2.4 Security-related Queries............................................................................................................ 16
2.2.5 Administrative Queries .............................................................................................................. 17
3 Mutations ............................................................................................................................... 19
3.1 Introduction ...................................................................................................................................... 19
3.2 Exercise Instructions ........................................................................................................................ 19
4 Parameters ............................................................................................................................. 21
4.1 Introduction ...................................................................................................................................... 21
4.2 Exercise Instructions ........................................................................................................................ 21
Appendix A. Solutions to the Questions ................................................................................. 24
1.1 GraphQL
GraphQL is a specification for a Query Language, about which you can read more on https://graphql.org/. It
was designed to overcome problems with RESTful interfaces. Like RESTful interfaces it also uses HTTP. A
key advantage of GraphQL is its flexibility to define what information should be contained in the response to
a request. Thus, what would be several different requests in traditional interfaces for FileNet Content
Platform Engine, can be combined into one GraphQL request to achieve higher efficiency.
Another advantage is that applications interfacing to GraphQL only require to send and receive HTTP
messages and can be written without binding with any specific FileNet Content Platform Engine Client
libraries. This results in less version dependencies, and easier upgrades of an environment using GraphQL to
access the FileNet Content Engine repositories.
For further reading, the FileNet P8 Platform Documentation contains some sections about developing with
the GraphQL API for Content Platform Engine: https://www.ibm.com/docs/en/filenet-p8-
platform/5.5.12?topic=development-overview.
Furthermore, there is also a white paper on the GraphQL interface, with lots of examples:
https://www.ibm.com/support/pages/sites/default/files/inline-
files/$FILE/IBM%20Content%20Services%20GraphQL%20API%20Developer%20Guide_1.pdf.
The exercise “GraphQL Queries” introduces you to the GraphQL query language in a series of short, easy to
understand examples. For this, it uses the Graph iQL component, which supports auto-completion and
content sensitive help. The target is not to cover the complete GraphQL query language, but to summarize
the key concepts to use the GraphQL FileNet Interface efficiently.
The exercise “Mutations” introduces the reader to performing changes on the FileNet Content Platform
Engine environment through GraphQL. In the examples, a folder will be created, its security settings
modified, and the folder deleted again.
The last exercise “Parameters” introduces the possibility to parameterize GraphQL queries, freeing a
custom application using the GraphQL interface from making a lot of string manipulations to build up the
final queries with the custom information required. This way, the GraphQL queries themselves can be
assembled in a kind of library, defined in constant strings.
_4. Enter the Username and Password which were supplied to you click Log in
For developing GraphQL requests, the GraphQL component of Cloud Pak for Business Automation allows to
enable the GraphiQL web application. It is used in the next exercises of this lab for exploring the FileNet
Content Platform Engine GraphQL implementation.
For security reasons, a production environment would normally not contain the GraphiQL web-
application, and that application is by default disabled. For accessing GraphQL there, GraphQL requests
can be sent as HTTP requests, the response is sent in JSON format.
When you are working with the GraphiQL interface for some time, it might be that at some moment the
session times out. When this is happening, instead of a query result (or an error) you will get a red error
message. To renew the session, it is enough to refresh the browser page.
As there is only one domain on a FileNet Content Manager environment, the section in parentheses (…) does
not need to be specified. The following output should be shown (the IDs, time stamps and user names might
be different in this and all further screenshots showing results, actually)
_3. Try searching for the “Domain” type in the online documentation, by placing the mouse over the query
keyword “domain” and waiting a couple seconds. The box which opens, informs that the domain
directive is of type "Domain", all the types shown in yellow color. Click on the yellow “Domain” to list the
Domain type and its properties. It should tell you, that following properties can be used in the stanza for
the “domain” query:
_6. Finally, this request might be extended to include data about the Object Stores of the domain too. Extend
the query as follows:
query domainquery {
domain {
id name
properties(includes: ["SystemUserName"]) {
id value
}
objectStores {
objectStores {
id symbolicName
}
}
}
}
This should show information about all the object stores defined in the Content Platform Engine
environment.
_7. How would a request look like which would print the name and value of the "DomainType" property as
well?
_4. Adding the list of subfolders is a bit more complex. The "subFolders" field is of type FolderSet. FolderSet
objects have a single field, which is named "folders" and expands to all folders contained in the
FolderSet. For each of these folders, you can query the id and the pathName for example. The pathName
lists the complete path as would be suitable for the content of the identifier in a following call.
query folderquery {
folder (
repositoryIdentifier:"CONTENT"
identifier:"/"
)
{
name id
subFolders {
folders {
id pathName
}
}
}
}
_5. Listing the contained documents works very similar. The field in the folder, which lists the documents
contained in the folder is named "containedDocuments" field, you can see it in the online documentation
when listing the parameters of the “Folder” type. It is of type DocumentSet, and its "documents" field
expands to the array of documents contained in the folder.
Each of the documents again has potentially many content elements, to which access is possible via the
“contentElements” field.
query folderquery {
folder (
repositoryIdentifier:"CONTENT"
identifier:"/SOLUTION Client Onboarding"
)
{
name id
containedDocuments {
documents {
id name creator dateCreated
majorVersionNumber minorVersionNumber
mimeType
contentElements {
className
contentType
elementSequenceNumber
}
}
}
}
}
_6. By hovering with the mouse over contentElements, it can be seen that contentElements is an array of
objects which all implement the ContentElement interface. That interface is implemented among others
by the type "ContentTransferType" which also implements the “ContentTransfer” interface. Follow the
online documentation as follows:
_7. By using a special notation, it can be specified, that if a Content Element implements the
ContentTransfer interface, further information should be retrieved. Extend the query as follows:
query folderquery {
folder (
repositoryIdentifier:"CONTENT"
identifier:"/SOLUTION Client Onboarding"
In the returned information, important further information is contained for content elements implementing
the “ContentTransfer” interface. Similarly further information could also be included for other
implementations, e.g. ones which implement the “ContentReference” interface. That is not shown here.
_8. For constructing the download URL, open a text editor (e.g. notepad if you are working on a Windows
machine) and copy the GraphQL URL address into it. Search for the first question mark and remove the
question mark and everything following it from the URL in the text editor. Then copy one of the
Note that you did not need to login again. The authentication done earlier will be reused on the new
browser tab, its stored in a cookie. Optionally, you can try the same but with using a private browser
window, then you would need to login again.
_2. With the query on “documents” you can search for documents. Using this kind of query, you can also
perform more complex searches, like for example queries using CBR clauses. This specific query will list
the folders where the documents are filed, along with the document ids, and also some custom
properties.
query documentsquery {
documents (
repositoryIdentifier:"CONTENT"
from: "SOLUTION_Client_Document d INNER JOIN ContentSearch c ON d.This =
c.QueriedObject"
where: "CONTAINS(d.*, 'Automation Elite')"
)
{
documents {
id
className
properties(includes: ["Name", "SWAT_Client_Name"]) {
id value
}
foldersFiledIn {
folders {
pathName
}
}
_3. You can actually also combine multiple queries into a single GraphQL request, to further reduce the
number of roundtrips of your application to the Content Engine Server, e.g. to increase the overall
performance, especially on slow networks, or networks with a high latency. This below query gets
information from the domain, and also on the id of the root folder of the “CONTENT” repository
query multiquery {
domain {
name
objectStores {
objectStores {
displayName
}
}
}
folder (
repositoryIdentifier: "CONTENT"
identifier: "/"
) {
id
}
}
_4. Observe that in the output JSON data, the query keyword is used to store the result data.
_5. Try to use same query keyword twice and observe that an error is logged. The error occurs, since “folder”
cannot appear twice in the JSON output under the “data” entry.
query multiquery2 {
folder (
repositoryIdentifier: "CONTENT"
identifier: "/"
) {
id
}
folder (
repositoryIdentifier: "CONTENT"
identifier: "/Case Folders"
) {
id
}
}
_6. To fix it, make use of alias clauses, as follows, also to make the result a lot more self-explanatory.
query multiquery {
_3. Complete the query as follows as below. The result will give information about the logged-on user.
query whoami {
secCurrentUser {
name
displayName
memberOfGroups {
groups {
name
}
}
shortName
email
}
}
Depending on the user and the environment you would be getting a result similar to the following:
Other new queries and mutations (see below) of the Security group allow to query and update local groups,
and managed users.
A further area where new queries and mutations were made available is query, update and delete of
Document Classes, and Property Templates.
_1. The first example shows how to retrieve information about a class definition. In the query, the symbolic
name or object id of the class definition is needed, the information can for example be obtained from
querying a document. Notice that through the class definition also information about the property definitions
can be obtained.
Notice that information comes from the Property Definitions which might be different from the Property
Templates, which were used to define them.
query getClientInformationClassDetails {
clientInfoClass: admClassDefinition (repositoryIdentifier: "CONTENT",
identifier: "SOLUTION_Client_Information") {
symbolicName
propertyDefinitions {
dataType
symbolicName
isSystemOwned
... on PropertyDefinitionString {
maximumLengthString
}
... on PropertyDefinitionDateTime {
isDateOnly
}
}
}
}
The part between "{" and "}" has the same purpose as before, it specifies exactly what information should
be provided on the result of the request.
The permissions can also be updated. Up to version 5.5.10 of GraphQL, or version 22.0.2 of CP4BA, this can
only be done by replacing the whole set of permissions with a new set. With Version 5.5.11 of GraphQL, or
version 23.0.1 of CP4BA, the permissions can also be updated. The mutation for updating the security
settings for the folder created above will be shown later in its parameterized variant, in section 4.2.
_2. The folder can be deleted again by using the "deleteFolder" operation on the mutation, as follows (twice
replacing usrxx with your login):
mutation deletefolder {
deleteFolder (
repositoryIdentifier: "CONTENT"
identifier: "/usrxx GraphQL Folder"
) {
id
}
}
This can be solved by using parameters. This way, the GraphQL queries can be developed and can be defined
in a custom application as constant strings. Only the parameters need to be supplied, and they are using
JSON syntax.
The examples in this chapter will create the folder from the last chapter again, but this time the mutations
will be parameterized.
In the documentation, you find the description for the query parameters in this section:
https://www.ibm.com/docs/en/filenet-p8-platform/5.5.x?topic=mutations-v556-later-graphql-variables.
Find the section and click on it to expand it and allow values to be provided.
_2. For the syntax of the parameter type definitions, it is recommended to review how the online
documentation is writing the type and use the same notation. For a parameter holding the name of the
Object Store to work on, it would for example be denoted as "String!" similarly to following screenshot
from the online documentation:
_4. In the unfolded QUERY VARIABLES pane, type the opening "{" character to define the json object with
the parameter values. A menu appears with the three parameter names. This way it is pretty
straightforward to provide the required data. In the data below again substitute the username.
{"theRepo": "CONTENT",
"parentFolderId": "/",
"newFolderName": "usrxx GraphQL Folder"}
Execute the query to create the folder again.
_5. The next example shows that also more complex data structures, not only strings can be provided as
parameters. In this case a new permission set is passed as a parameter for a request to update the
folder security, or to be more precise to replace the complete permissions of the folder by a new set of
permissions. In the online documentation the permissions to be provided are documented to be having
this type:
With FileNet Content Services GraphQL 5.5.11 provided with Cloud Pak for Business Automation 23.0.1,
dependent object arrays can now also be updated, instead of replacing the whole list by a new one.
_7. The parameterized version for the deletion of the GraphQL folder is again left open as an exercise to the
reader. If you are performing this exercise as part of a SWAT JAM event, you can post the completed
query on the slack channel for the event.
Congratulations you have successfully completed the lab “Interfacing FileNet Content Platform Engine with
GraphQL on Cloud Pak for Business Automation”!
_2. The parameterized form for deleting a folder can be derived from the non-parameterized one given as an
example earlier. Here is the one without parameters first, with the values underlines which should be
parameterized:
mutation deletefolder {
deleteFolder (
repositoryIdentifier: "CONTENT"
identifier: "/usrxx GraphQL Folder"
) {
id
}
}