2. Paul Withers
ICS Consultant, Intec Systems Ltd
IBM Champion since 2011
OpenNTF Board Member
WWS Java SDK developer
2#engageug
3. Philippe Riand
CTO of Trilog Group & Darwino Inc.
Former application development
chief architect for
IBM Collaboration Services
Chief architect, and inventor,
of IBM Domino XPages
3#engageug
4. The Problem With REST
Multiple calls required
• “Joins” are consumer’s responsibility
• May result in a large number of REST calls –> Latency is multiplied by
the number of calls -> sequential behaviour
Provider-driven
• Consumer gets what they get, needs to parse accordingly
Versions
• Changes typically require version increment
• May affect consumer’s application object model
Validation
• Request cannot be validated prior to submission
4#engageug
6. What Is GraphQL?
Created by Facebook 2012
Specification for standard began 2015
Query language
• Not database architecture
• Not programming language
• A modern way to expose your API and give your clients more Control
on what they get
6#engageug
7. Why GraphQL?
Consumer-driven
• Returns what the client asks for and no more!
Hierarchical
• Query and response are both JSON, in same hierarchical structure
Strongly Typed
• GraphQL type structure ensures query can be tested for syntactical
correctness and validity before execution
Introspective
• GraphQL language can be used to query the type structure
7#engageug
8. GraphQL
• Open source in-browser IDE https://github.com/graphql/graphiql
• Build validated and syntactically correct queries /
mutations and fragments
• Define query variables
• Run queries and browse response
• Run a query to introspect schema
• Drill down through schema documentation
• Visualizer tools also available
http://nathanrandal.com/graphql-visualizer/
8#engageug
10. GraphQL and Watson Work Services
• Documentation online
https://workspace.ibm.com/developer/docs
• GraphiQL tool for WWS
https://workspace.ibm.com/graphql
• Must be authenticated in browser to Watson Workspace first!
• Queries run as user, not application
• Some queries are not available to applications
• Additional REST endpoints exist (e.g. authentication,
focus, photos)
• These are usually version-based, e.g. …/v1/…
10#engageug
12. GraphQL Query Structure
Query can have operation name, optional if only one query
Query object has fields for things that can be returned
Fields may take (or require) arguments
• Arguments have a type (String, Int, ID etc)
• See GraphQL documentation for more details
• Required arguments have “!” after the type in documentation (e.g.
space(id:ID!)
• Argument values may be literal or map to variables
12#engageug
13. GraphQL Query Structure
Variables
• Passed as an argument of the operation name
• Format is “$VariableName: Type” (e.g. $FIRST: Int)
• Passed to value of an argument in the operation
• Declared as a separate JSON object
• Key is variable name as a String
• Value is variable value
• Validated in GraphiQL IDE, like rest of query
13#engageug
14. GraphQL Query Structure
Fields may have an alias
• Format is “alias: field”
• Allows query to retrieve multiple result objects of same field type
• In response, field type is replaced with alias
Fields will themselves have fields and/or objects to return
14#engageug
15. GraphQL Query Structure
Queries on lists may return lots of objects
“Slice” using first and last
Return pageInfo object to get cursor
Pass cursor back to query using before or after
15#engageug
16. GraphQL Query Structure
Fragments can be included to improve readability of
complex queries
• Defined as separate JSON object
• Format is “fragment fragmentName on type”
• Allows fields to be defined and validated inline
• Used with format “…fragmentName”
Schema may return an interface or union type
• Inline fragment may be required to act differently depending on
actual implementation from interface
• Format is “… on type”
• Not used in WWS, see GraphQL documentation for examples
16#engageug
20. GraphQL Mutations
Mutation can have an operation name
Declares the field to set (function)
Pass an input object to the field
Returns a type
• May just be a scalar (e.g. true / false)
• May be an object (e.g. a space)
• If an object, that can be queried, as in a query
Can pass multiple fields (processed sequentially)
20#engageug
21. GraphQL Subscriptions
Subscription allows clients to receive updates
Declares the field to subscribe to
Pass an input object to the field, including subscription id
Nothing yet implemented for this in Watson Work Services
21#engageug
22. Introspecting GraphQL Schema
GraphQL schema can be introspected with GraphQL query!
• __schema queries the schema
• __type introspects a specific type
• kind introspects field type
• If NON_NULL, ofType returns its actual type
“It’s GraphQL queries all the way down”
22#engageug
23. GraphQL – Real World Implementations
- Facebook
- Watson Works Services
- Darwino (OpenSource Project hosted on OpenNTF and
darwino.org)
- Connections Pink
23#engageug
24. Darwino GraphQL Implementation
Darwino is providing a set of open source libraries for both
consumers and producers of GraphQL
The libraries are part of the Darwino core code but hosted
on OpenNTF/darwino.org
The code depends on some core Darwino classes (JSON,
utilities…) but these are part of Darwino community edition
24#engageug
25. Schemaless GraphQL Queries
GraphQL uses static schemas to validate the queries and
make them discoverable by tools (code completion…)
This forces the queries to be fully defined on the producer
side
All the fields have to be predefined
All the relations between data sets have to be predefined as well
What about semi structured data, like Domino documents?
-> Would benefit from more flexibility
To seamlessly access the data in an unstructured document
To make prototyping easier and faster
To traverse relations that are not known upfront
25#engageug
26. Dynamic JSON Data Type
A JSON data type is a GraphQL type that exposes its
content as a virtual JSON Object
Its dynamic content is accessed using pseudo fields extract
the value using JSON Path
26#engageug
27. A Simple Domino Example
Reading items from an existing Domino document
DominoDocument is a pseudo field loading a document
based on parameters, and returning a JSON data type
string is a pseudo field extracting a string value from a
JSON data type using a JSON path
27#engageug
doc: DominoDocument(database:"DarwinoReports.nsf",
unid:"DD2028D6B53ADCCB852581080009C40E") {
_unid,
code: string(path:"PRODUCTCODE"),
name: string(path:"PRODUCTNAME"),
}
https://playground.darwino.com/playground.nsf/GraphqlSnippets.xsp#snippet=Notes_Domino_Read_Document
28. Dynamic JSON Types
Dynamic JSON types are pseudo fields that can be added
any object
By convention, these fields start with a capital letter, like a
class in Java: DominoDocument, DominoView…
They are used with an alias to name the result field
Dynamic types are contributed by extension points,then
added to every type in the final GraphQL schema.
28#engageug
view: DominoView(name: “myview”){
…
doc: DominoDocument(unid: ‘xxx’) {
…
}
}
29. Dynamic JSON Fields
Dynamic fields are also peudo fields, extracting a value
using a JSON path and coercing the result to the desired
type:
New dynamic fields can be added by the developers
29#engageug
val: string(path:“a.b.c")
val: number(path:“a.b.c")
val: int:“a.b.c")
val: long(path:“a.b.c")
val: boolean(path:“a.b.c")
val: value(path:“a.b.c")
val: eval(formula:“@Trim(@UserName)")
30. JSON Path Introduction
A JSON Path is to JSON what an XPath is to XML
The syntax is closed to JavaScript, starting with a ‘$’
$.firstName
$.spouse.firstName
$.spouse[‘firstName’]
$.addresses[1].street
$ {whole document}
There are more complex operators
http://goessner.net/articles/JsonPath/
Darwino core provides a high performance, advanced
JSON Path engine
30#engageug
{
firstName: ‘Barak’,
spouse: {
firstName: ‘Michele’,
…
}
addresses: [
{ street: ‘Main St’, …},
{ street: ‘Bob Sq’, …},
],
…
}
31. Static Fields
A JSON dynamic type can mix and match static fields with
dynamic ones
By convention, system fields start with a ‘_’ (_unid, …)
Functional static fields can be added
31#engageug
DominoDocument(database:"DarwinoReports.nsf",
unid:"DD2028D6B53ADCCB852581080009C40E") {
_unid,
_noteId,
_created,
_lastAccessed,
user {
cn, dn
}
name: string(path:"PRODUCTNAME"),
}
32. Passing Parameters to JSON Types
In the previous Domino example, the unid parameter is
hard coded which is not that useful…
unid can be set from a GraphQL variable, but this is also
global to the request – cannot be used for relations
Darwino implementation uses a special syntax to calculate
parameters
Delegates the evaluation of ‘docid’ to the parent object
Drawback: all parameters have to be declared as strings in GraphQL
32#engageug
doc: DominoDocument(unid:$VAR)
doc: DominoDocument(unid:”${docid}”)
35. Java Client Builder
• A GraphQL query is a text file that is always painful to
build safely
• Escaping the text pieces, quotes…
• Making sure that all the braces { } are balanced
• Format it to be either compacted or developer friendly
• Darwino provides an easy to use builder to help the
creation of queries in Java
• Highly readable by developer
• Supports code completion in a Java IDE
• Based on the Java Builder pattern
• Fully extensible to handle known objects
35#engageug
37. Example from the Playground
Putting it altogether…
37#engageug
String q = new GQuery("example")
.field(new GField("Document")
.attribute("unid", "1000")
.attribute("database", "playground")
.attribute("store", "pinball")
.field("_id")
.field("_unid")
.field("_cdate")
.field("_muser")
.stringField("name","name")
.stringField("manufacturer","manufacturer")
.numberField("released","released")
.longField("players","players")
.intField("flippers","flippers")
).build();
https://playground.darwino.com/playground.nsf/JavaSnippets.xsp#snippet=GraphQL_Run_Inline_Client_Query
38. Watson Work Services Java SDK
Java SDK for Watson Work Service
• On OpenCode4Workspace (run by OpenNTF)
• Download the project
• Consume from Maven
<dependency>
<groupId>org.opencode4workspace.watson-work-services</groupId>
<artifactId>wws-api</artifactId>
<version>0.6.0</version>
</dependency>
• View source code on Stash (includes Junit tests)
• Explore implementation in Watson Workspace for Eclipse / Notes
Latest documentation on OpenNTF Wiki, Javadoc available
38#engageug
39. Watson Work Services Java SDK
Client authentication as application
Client authentication as user
Build queries with Java objects, methods and enums
• No need to construct queries as complex Strings
Methods to output built query as String and response as
String
Conversion of response to Java objects
Methods to parse error responses
Standard REST endpoints also supported
39#engageug
42. WWS Java SDK
Variables not current supported
• Use Java method to construct query based on variable
Fragments not currently supported
• Use Java method / object to specify standard fields
Directives not currently supported
• Use Java method to construct query based on variable
Aliases not currently supported
• Track the JIRA issue
42#engageug
44. Thank You
44#engageug
Paul Withers
Intec Systems Ltd & OpenNTF
pwithers@intec.co.uk
@paulswithers
https://www.intec.co.uk/blog
https://paulswithers.github.io
Philippe Riand
Darwino Inc.
phil@darwino.com
@philriand
http://blog.riand.com/
https://www.darwino.com/