Skip to content

Commit d1d1a24

Browse files
committed
moves documentation to be V12 latest
1 parent 9a43020 commit d1d1a24

24 files changed

+3721
-5
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ public
33
.idea
44
dist
55
node_modules
6-
.vscode
6+
.vscode
7+
*.iml

config.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ theme = "hugo-sustain"
55
pygmentsUseClasses=true
66

77
[params]
8-
latestReleases = ["v9.4", "v11.0"]
9-
latestDocs = "v11"
8+
latestReleases = ["v9.5", "v12.0"]
9+
latestDocs = "v12"
1010

1111
## Main Menu
1212
[[menu.main]]
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
---
22
title: "Documentation"
33
date: 2018-09-09T18:19:33+06:00
4-
aliases: [/documentation/latest/]
54
---
65
graphql-java documentation
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
title: "Documentation"
3+
date: 2018-09-09T18:19:33+06:00
4+
aliases: [/documentation/latest/]
5+
---
6+
graphql-java documentation

content/documentation/v12/batching.md

Lines changed: 396 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
---
2+
title: "Concerns"
3+
date: 2018-09-09T12:52:46+10:00
4+
draft: false
5+
tags: [documentation]
6+
weight: 111
7+
description: Outlines certain application level concerns and how to address them
8+
---
9+
# Application concerns
10+
11+
The graphql-java library concentrates on providing an engine for the execution of queries according to the specification.
12+
13+
It does not concern itself about other high level application concerns such as the following :
14+
15+
- Database access
16+
- Caching data
17+
- Data authorisation
18+
- Data pagination
19+
- HTTP transfer
20+
- JSON encoding
21+
- Code wiring via dependency injection
22+
23+
You need to push these concerns into your business logic layers.
24+
25+
The following are great links to read more about this
26+
27+
- http://graphql.org/learn/serving-over-http/
28+
- http://graphql.org/learn/authorization/
29+
- http://graphql.org/learn/pagination/
30+
- http://graphql.org/learn/caching/
31+
32+
## Context Objects
33+
34+
You can pass in a context object during query execution that will allow you to better invoke that business logic.
35+
36+
For example the edge of your application could be performing user detection and you need that information inside the
37+
graphql execution to perform authorisation.
38+
39+
This made up example shows how you can pass yourself information to help execute your queries.
40+
41+
{{< highlight java "linenos=table" >}}
42+
43+
//
44+
// this could be code that authorises the user in some way and sets up enough context
45+
// that can be used later inside data fetchers allowing them
46+
// to do their job
47+
//
48+
UserContext contextForUser = YourGraphqlContextBuilder.getContextForUser(getCurrentUser());
49+
50+
ExecutionInput executionInput = ExecutionInput.newExecutionInput()
51+
.context(contextForUser)
52+
.build();
53+
54+
ExecutionResult executionResult = graphQL.execute(executionInput);
55+
56+
// ...
57+
//
58+
// later you are able to use this context object when a data fetcher is invoked
59+
//
60+
61+
DataFetcher dataFetcher = new DataFetcher() {
62+
@Override
63+
public Object get(DataFetchingEnvironment environment) {
64+
UserContext userCtx = environment.getContext();
65+
Long businessObjId = environment.getArgument("businessObjId");
66+
67+
return invokeBusinessLayerMethod(userCtx, businessObjId);
68+
}
69+
};
70+
71+
{{< / highlight >}}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
title: "Contributions"
3+
date: 2018-09-09T12:52:46+10:00
4+
draft: false
5+
tags: [documentation]
6+
weight: 1000
7+
description: Every contribution to make this project better is welcome. Thank you!
8+
---
9+
# Contributions
10+
11+
Every contribution to make this project better is welcome: Thank you!
12+
13+
In order to make this a pleasant as possible for everybody involved, here are some tips:
14+
15+
* Respect the [Code of Conduct](#code-of-conduct)
16+
17+
* Before opening an Issue to report a bug, please try the latest development version. It can happen that the problem is already solved.
18+
19+
* Please use Markdown to format your comments properly. If you are not familiar with that: [Getting started with writing and formatting on GitHub](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github)
20+
21+
* For Pull Requests:
22+
* Here are some [general tips]( https://github.com/blog/1943-how-to-write-the-perfect-pull-request)
23+
24+
* Please be a as focused and clear as possible and don't mix concerns. This includes refactorings mixed with bug-fixes/features, see [Open Source Contribution Etiquette](http://tirania.org/blog/archive/2010/Dec-31.html)
25+
26+
* It would be good to add a automatic test. All tests are written in [Spock](http://spockframework.github.io/spock/docs/1.0/index.html).
27+
28+
## Build and test locally
29+
30+
Just clone the repo and type
31+
32+
{{< highlight sh "linenos=table" >}}
33+
34+
./gradlew build
35+
{{< / highlight >}}
36+
<br/>
37+
In `build/libs` you will find the jar file.
38+
39+
Running the tests:
40+
41+
{{< highlight sh "linenos=table" >}}
42+
43+
./gradlew test
44+
{{< / highlight >}}
45+
46+
Installing in the local Maven repository:
47+
48+
{{< highlight sh "linenos=table" >}}
49+
50+
./gradlew install
51+
{{< / highlight >}}
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
---
2+
title: "Data fetching"
3+
date: 2018-09-09T12:52:46+10:00
4+
draft: false
5+
tags: [documentation]
6+
weight: 102
7+
description: How graphql-java fetches data for each of the fields in a query
8+
---
9+
# Fetching data
10+
11+
## How graphql fetches data
12+
13+
Each field in graphql has a `graphql.schema.DataFetcher` associated with it.
14+
15+
Some fields will use specialised data fetcher code that knows how to go to a database say to get field information while
16+
most simply take data from the returned in memory objects using the field name and Plain Old Java Object (POJO) patterns
17+
to get the data.
18+
19+
`Note : Data fetchers are some times called "resolvers" in other graphql implementations.`
20+
21+
So imagine a type declaration like the one below :
22+
23+
24+
{{< highlight graphql "linenos=table" >}}
25+
type Query {
26+
products(match : String) : [Product] # a list of products
27+
}
28+
29+
type Product {
30+
id : ID
31+
name : String
32+
description : String
33+
cost : Float
34+
tax : Float
35+
launchDate(dateFormat : String = "dd, MMM, yyyy') : String
36+
}
37+
{{< / highlight >}}
38+
39+
40+
The `Query.products` field has a data fetcher, as does each field in the type ``Product``.
41+
42+
The data fetcher on the ``Query.products`` field is likely to be a more complex data fetcher, containing code that
43+
goes to a database say to get a list of ``Product`` objects. It takes an optional ``match`` argument and hence can filter these
44+
product results if the client specified it.
45+
46+
It might look like the following :
47+
48+
{{< highlight java "linenos=table" >}}
49+
DataFetcher productsDataFetcher = new DataFetcher<List<ProductDTO>>() {
50+
@Override
51+
public List<ProductDTO> get(DataFetchingEnvironment environment) {
52+
DatabaseSecurityCtx ctx = environment.getContext();
53+
54+
List<ProductDTO> products;
55+
String match = environment.getArgument("match");
56+
if (match != null) {
57+
products = fetchProductsFromDatabaseWithMatching(ctx, match);
58+
} else {
59+
products = fetchAllProductsFromDatabase(ctx);
60+
}
61+
return products;
62+
}
63+
};
64+
{{< / highlight >}}
65+
66+
67+
Each ``DataFetcher`` is passed a ``graphql.schema.DataFetchingEnvironment`` object which contains what field is being fetched, what
68+
arguments have been supplied to the field and other information such as the field's type, its parent type, the query root object or the query
69+
context object.
70+
71+
Note how the data fetcher code above uses the ``context`` object as an application specific security handle to get access
72+
to the database. This is a common technique to provide lower layer calling context.
73+
74+
Once we have a list of ``ProductDTO`` objects we typically don't need specialised data fetchers on each field. graphql-java
75+
ships with a smart ``graphql.schema.PropertyDataFetcher`` that knows how to follow POJO patterns based
76+
on the field name. In the example above there is a ``name`` field and hence it will try to look for a ``public String getName()``
77+
POJO method to get the data.
78+
79+
80+
``graphql.schema.PropertyDataFetcher`` is the data fetcher that is automatically associated with each field by default.
81+
82+
You can however still get access to the ``graphql.schema.DataFetchingEnvironment`` in your DTO methods. This allows you to
83+
tweak values before sending them out. For example above we have a ``launchDate`` field that takes an optional ``dateFormat``
84+
argument. We can have the ProductDTO have logic that applies this date formatting to the desired format.
85+
86+
87+
{{< highlight java "linenos=table" >}}
88+
class ProductDTO {
89+
90+
private ID id;
91+
private String name;
92+
private String description;
93+
private Double cost;
94+
private Double tax;
95+
private LocalDateTime launchDate;
96+
97+
// ...
98+
99+
public String getName() {
100+
return name;
101+
}
102+
103+
// ...
104+
105+
public String getLaunchDate(DataFetchingEnvironment environment) {
106+
String dateFormat = environment.getArgument("dateFormat");
107+
return yodaTimeFormatter(launchDate,dateFormat);
108+
}
109+
}
110+
111+
{{< / highlight >}}
112+
113+
114+
## Customising PropertyDataFetcher
115+
116+
As mentioned above ``graphql.schema.PropertyDataFetcher`` is the default data fetcher for fields in graphql-java and it will use standard patterns for fetching
117+
object field values.
118+
119+
It supports a ``POJO`` approach and a ``Map`` approach in a Java idiomatic way. By default it assumes that for a graphql field ``fieldX`` it can find a POJO property
120+
called ``fieldX`` or a map key called ``fieldX`` if the backing object is a ``Map``.
121+
122+
However you may have small differences between your graphql schema naming and runtime object naming. For example imagine that ``Product.description`` is actually
123+
represented as ``getDesc()`` in the runtime backing Java object.
124+
125+
If you are using SDL to specify your schema then you can use the ``@fetch`` directive to indicate this remapping.
126+
127+
{{< highlight graphql "linenos=table" >}}
128+
directive @fetch(from : String!) on FIELD_DEFINITION
129+
130+
type Product {
131+
id : ID
132+
name : String
133+
description : String @fetch(from:"desc")
134+
cost : Float
135+
tax : Float
136+
}
137+
138+
{{< / highlight >}}
139+
140+
This will tell the ``graphql.schema.PropertyDataFetcher`` to use the property name ``desc`` when fetching data for the graphql field named ``description``.
141+
142+
If you are hand coding your schema then you can just specify it directly by wiring in a field data fetcher.
143+
144+
{{< highlight java "linenos=table" >}}
145+
146+
GraphQLFieldDefinition descriptionField = GraphQLFieldDefinition.newFieldDefinition()
147+
.name("description")
148+
.type(Scalars.GraphQLString)
149+
.build();
150+
151+
GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry()
152+
.dataFetcher(
153+
coordinates("ObjectType", "description"),
154+
PropertyDataFetcher.fetching("desc"))
155+
.build();
156+
157+
158+
{{< / highlight >}}
159+
160+
161+
## The interesting parts of the DataFetchingEnvironment
162+
163+
Every data fetcher is passed a ``graphql.schema.DataFetchingEnvironment`` object which allows it to know more about what is being fetched
164+
and what arguments have been provided. Here are some of the more interesting parts of ``DataFetchingEnvironment``.
165+
166+
* ``<T> T getSource()`` - the ``source`` object is used to get information for a field. Its the object that is the result
167+
of the parent field fetch. In the common case it is an in memory DTO object and hence simple POJO getters will be used for fields values. In more complex cases, you may examine it to know
168+
how to get the specific information for the current field. As the graphql field tree is executed, each returned field value
169+
becomes the ``source`` object for child fields.
170+
171+
* ``<T> T getRoot()`` - this special object is used to seed the graphql query. The ``root`` and the ``source`` is the same thing for the
172+
top level fields. The root object never changes during the query and it may be null and hence no used.
173+
174+
* ``Map<String, Object> getArguments()`` - this represents the arguments that have been provided on a field and the values of those
175+
arguments that have been resolved from passed in variables, AST literals and default argument values. You use the arguments
176+
of a field to control what values it returns.
177+
178+
* ``<T> T getContext()`` - the context is object is set up when the query is first executed and stays the same over the lifetime
179+
of the query. The context can be any value and is typically used to give each data fetcher some calling context needed
180+
when trying to get field data. For example the current user credentials or the database connection parameters could be contained
181+
with a ``context`` object so that data fetchers can make business layer calls. One of the key design decisions you have as a graphql
182+
system designer is how you will use context in your fetchers if at all. Some people use a dependency framework that injects context into
183+
data fetchers automatically and hence don't need to use this.
184+
185+
186+
* ``ExecutionStepInfo getExecutionStepInfo()`` - the field type information is a catch all bucket of field type information that is built up as
187+
the query is executed. The following section explains more on this.
188+
189+
* ``DataFetchingFieldSelectionSet getSelectionSet()`` - the selection set represents the child fields that have been "selected" under neath the
190+
currently executing field. This can be useful to help look ahead to see what sub field information a client wants. The following section explains more on this.
191+
192+
* ``ExecutionId getExecutionId()`` - each query execution is given a unique id. You can use this perhaps on logs to tag each individual
193+
query.
194+
195+
196+
197+
198+
## The interesting parts of ExecutionStepInfo
199+
200+
The execution of a graphql query creates a call tree of fields and their types. ``graphql.execution.ExecutionStepInfo.getParentTypeInfo``
201+
allows you to navigate upwards and see what types and fields led to the current field execution.
202+
203+
Since this forms a tree path during execution, the ``graphql.execution.ExecutionStepInfo.getPath`` method returns the representation of that
204+
path. This can be useful for logging and debugging queries.
205+
206+
There are also helper methods there to help you get the underlying type name of non null and list wrapped types.
207+
208+
209+
## The interesting parts of DataFetchingFieldSelectionSet
210+
211+
Imagine a query such as the following
212+
213+
214+
{{< highlight graphql "linenos=table" >}}
215+
query {
216+
products {
217+
# the fields below represent the selection set
218+
name
219+
description
220+
sellingLocations {
221+
state
222+
}
223+
}
224+
}
225+
{{< / highlight >}}
226+
227+
228+
The sub fields here of the ``products`` field represent the selection set of that field. It can be useful to know what sub selection has been asked for
229+
so the data fetcher can optimise the data access queries. For example an SQL backed system may be able to use the field sub selection to
230+
only retrieve the columns that have been asked for.
231+
232+
In the example above we have asked for ``sellingLocations`` information and hence we may be able to make an more efficient data access query where
233+
we ask for product information and selling location information at the same time.
234+

0 commit comments

Comments
 (0)