Deep Dive into Selection
Selection lets you select fields that you want to fetch from the query on a particular type.
SwiftGraphQL generates phantom types for your operations, objects, interfaces and unions. You can use these in combination with Selection
type to generate a concrete type for your selection (e.g. Selection<String, Objects.Human>
). You can find all generated phantom types by typing
Unions.
Interfaces.
Objects.
Operations.
followed by a name from your GraphQL schema.
Most of the time, however, you should use Selection.
that contains type-alias for unions, interfaces, objects and operations. In that case, you don’t have to specify the type-lock anymore and simply provide the return type (e.g. Selection.Human<String>
).
Selecting Fields
Unions
When fetching a union you should provide selections for each of the union sub-types. Additionally, all of those selections should resolve to the same type.
You’d usually want to create a Swift enumerator and have different selecitons return different cases.
Interfaces
Interfaces are very similar to unions. The only difference is that you may query for a common field from the intersection.
Transforming Selections
Nullable, List, and Non-Nullable Selection
Selection packs a collection of utility functions that let you select nullable and list fields using your existing selecitons. Each selection comes with three calculated properties that let you do that:
list
- to query listsnullable
- to query nullable fieldsnonNullOrFail
- to query nullable fields that should be there
You can achieve the same effect using Selection
static functions .list
, .nullable
, and .nonNullOrFail
.
Making selection on the entire type
You might want to write a selection on the entire type from the selection composer itself. This usually happens if you have a distinct identifier reused in many types.
Consider the following scenario where we have an id
field in Human
type. There are many cases where we only query id
field from the Human
that’s why we create a human id selection.
Now, we want to reuse that same selection when query a detailed human type. To do that, we can use selection
helper method that lets you make a selection on the whole TypeLock
from inside the selection.
An alternative approach would be to manually rewrite the selection inside Human
again.
Having distinct types for ids of different object types is particularly useful in large projects as it gives you verification that you are not using a wrong identifier for a particular type of field. At first, this might seem useless and cumbersome, but it makes your code more robust once you get used to it.
Mapping Selection
You might want to map the result of your selection to a new type and get a selection for that new type.
You can do that by calling a map
function on selection and provide a mapping.
⚠️ Don’t make any nested calls to the API. Use the first half of the initializer to fetch all the data and return the calculated result. Just don’t make nested requests.
Validating Data
Since SwiftGraphQL uses functions to create selections, you may validate recieved data before turning it into a Swift structure. This way, you can use more structure to represent your data and make stricter requirements than those imposed by schema.
You can easily terminate resolution by throwing an error inside your selection.
NOTE: Always make all selection before throwing errors!
NOTE:
age
andisGoodDog
values are nullable in our schema but aren’t nullable in our model.
Operations on selection
Selections are quite useless on their own - they feel a bit like skeletons. Their true (and only) power comes from the two functions they expose - query
and decode
.
query
returns a spec-compliant GraphQL query and a variable set that you should use in your request.decode
accepts the body of the response and returns the decoded result.
query
anddecode
don’t actually communicate with the server. To do that, use one of the official clients or create your own.
Besides
query
anddecode
selection also contains wide range of utility functions that help you understand the structure of a given query. Those functions won’t be covered here. You should follow their comments to understand what they do and examine official clients to see how they are used.