|
| 1 | +--- |
| 2 | +title: "Field selection" |
| 3 | +date: 2018-09-09T12:52:46+10:00 |
| 4 | +draft: false |
| 5 | +tags: [documentation] |
| 6 | +weight: 112 |
| 7 | +description: Field selection |
| 8 | +--- |
| 9 | +# Field Selection |
| 10 | + |
| 11 | +Field selection occurs when you have a compound type (an object or interface type) and you select a set of sub fields |
| 12 | +from that type. |
| 13 | + |
| 14 | +For example given the following query : |
| 15 | + |
| 16 | +{{< highlight graphql "linenos=table" >}} |
| 17 | + query { |
| 18 | + user(userId : "xyz") { |
| 19 | + name |
| 20 | + age |
| 21 | + weight |
| 22 | + friends { |
| 23 | + name |
| 24 | + } |
| 25 | + } |
| 26 | + } |
| 27 | + |
| 28 | +{{< / highlight >}} |
| 29 | + |
| 30 | +The field selection set of the ``user`` field is ``name``, ``age``, ``weight``, ``friends`` and ``friends/name`` |
| 31 | + |
| 32 | +Knowing the field selection set can help make ``DataFetcher``s more efficient. For example in the above query |
| 33 | +imagine that the ``user`` field is backed by an SQL database system. The data fetcher could look ahead into the field selection |
| 34 | +set and use different queries because it knows the caller wants friend information as well as user information. |
| 35 | + |
| 36 | +``graphql.schema.DataFetchingFieldSelectionSet`` is used to represent this field selection set. It gives you maps |
| 37 | +of the fields and their ``graphql.schema.GraphQLFieldDefinition``s and argument values. |
| 38 | + |
| 39 | + |
| 40 | +{{< highlight java "linenos=table" >}} |
| 41 | + DataFetcher smartUserDF = new DataFetcher() { |
| 42 | + @Override |
| 43 | + public Object get(DataFetchingEnvironment env) { |
| 44 | + String userId = env.getArgument("userId"); |
| 45 | + |
| 46 | + DataFetchingFieldSelectionSet selectionSet = env.getSelectionSet(); |
| 47 | + if (selectionSet.contains("user/*")) { |
| 48 | + return getUserAndTheirFriends(userId); |
| 49 | + } else { |
| 50 | + return getUser(userId); |
| 51 | + } |
| 52 | + } |
| 53 | + }; |
| 54 | + |
| 55 | +{{< / highlight >}} |
| 56 | + |
| 57 | +A glob path matching system is used for addressing fields in the selection. Its based on ``java.nio.file.FileSystem#getPathMatcher`` |
| 58 | +as an implementation. |
| 59 | + |
| 60 | +This will allow you to use ``*``, ``**`` and ``?`` as special matching characters such that ``invoice/customer*`` would |
| 61 | +match an ``invoice`` field with child fields that start with ``customer``. Each level of field is separated by ``/`` just like |
| 62 | +a file system path. |
| 63 | + |
| 64 | +There are methods that allow you to get more detailed information about the fields in the selection set. For example |
| 65 | +if you are using [Relay](https://facebook.github.io/relay/docs/en/graphql-server-specification.html) often you want to know what fields have |
| 66 | +been request in the ``Connection`` section of the query. |
| 67 | + |
| 68 | +So given a query like: |
| 69 | + |
| 70 | +{{< highlight graphql "linenos=table" >}} |
| 71 | + query { |
| 72 | + users(first:10) { |
| 73 | + edges { |
| 74 | + node { |
| 75 | + name |
| 76 | + age |
| 77 | + weight |
| 78 | + friends { |
| 79 | + name |
| 80 | + } |
| 81 | + } |
| 82 | + } |
| 83 | + } |
| 84 | + } |
| 85 | + |
| 86 | +{{< / highlight >}} |
| 87 | + |
| 88 | + |
| 89 | +you can write code that gets the details of each specific field that matches a glob. |
| 90 | + |
| 91 | + |
| 92 | +{{< highlight java "linenos=table" >}} |
| 93 | + DataFetchingFieldSelectionSet selectionSet = env.getSelectionSet(); |
| 94 | + List<SelectedField> nodeFields = selectionSet.getFields("edges/nodes/*"); |
| 95 | + nodeFields.forEach(selectedField -> { |
| 96 | + System.out.println(selectedField.getName()); |
| 97 | + System.out.println(selectedField.getFieldDefinition().getType()); |
| 98 | + |
| 99 | + DataFetchingFieldSelectionSet innerSelectionSet = selectedField.getSelectionSet(); |
| 100 | + // this forms a tree of selection and you can get very fancy with it |
| 101 | + } |
| 102 | + |
| 103 | + |
| 104 | +{{< / highlight >}} |
| 105 | + |
0 commit comments