The following is the first few sections of a chapter from The Busy Coder's Guide to Android Development, plus headings for the remaining major sections, to give you an idea about the content of the chapter.


Aliases

Phil Karlton coined a popular programming maxim:

There are only two hard things in Computer Science: cache invalidation and naming things.

Naming things is a challenge because not everbody agrees on the name. Sometimes, we cannot even agree on a naming convention (such as a naming_convention, a namingConvention, or a NamingConvention).

Aliases allow you, on the client side, to tell the server how to name things. These aliases then impact the JSON that is returned to you.

On the surface, this may not seem all that interesting, as developers are used to having to conform to somebody else’s NAMING_CONVENTION. However, due to the way that GraphQL allows clients to “shape” the responses coming from the server, aliases also play a role in batched requests.

Applying Aliases

Let’s go back to one of the earlier GraphQL requests that we made:

query all {
  allTrips {
    id
    title
  }
}
That gives a raw JSON result that looks like:

{
  "data": {
    "allTrips": [
      {
        "id": "2c494055-78bc-430c-9ab7-19817f3fc060",
        "title": "Vacation!"
      },
      {
        "id": "e323fed5-6805-4bcf-8cb6-8b7a5014a9d9",
        "title": "Business Trip"
      }
    ]
  }
}

The data gives us an allTrips property, containing the data that we requested — in this case, an array of Trip objects, for which we only wanted the id and title fields.

The reason that property is named allTrips is because we requested the allTrips field from the root query object. The field that you query (or mutate) is the default name used for the results from that query or mutation.

However, through aliases, we can rename that property to something else:

query all {
  stuff: allTrips {
    id
    title
  }
}

Here, we have applied an alias of stuff to the allTrips field. Now, our response has a stuff property instead of an allTrips property:

{
  "data": {
    "stuff": [
      {
        "id": "2c494055-78bc-430c-9ab7-19817f3fc060",
        "title": "Vacation!"
      },
      {
        "id": "e323fed5-6805-4bcf-8cb6-8b7a5014a9d9",
        "title": "Business Trip"
      }
    ]
  }
}

This may not seem especially useful. However, aliases are key to unlocking a few other GraphQL features, particularly for cases where we cannot use the original field names… perhaps because we are querying or mutating that field more than once.

One, Two, Many, Lots

(the title of this section comes courtesy of the late Terry Pratchett and the Discworld novels)

So far, we have requested just one field in our queries, and mutated just one field in our mutations. You might think that this is a limitation of GraphQL.

It’s not.

It is just a limitation of trying to teach GraphQL, slowly advancing through its roster of features. In truth, a single query can retrieve many fields, and a single mutation can modify lots of fields.

Multiple Root Fields

The queries that we have used so far have requested just one root field. You can request as many as you want:

query allAndFind($search:String!) {
  allTrips {
    id
    title
  }
  findTrips(searchFor:$search) {
    id
    title
  }
}

Executing the allAndFind operation will return results for both the allTrips field and the findTrips field (given a value for $search):

{
  "data": {
    "allTrips": [
      {
        "id": "2c494055-78bc-430c-9ab7-19817f3fc060",
        "title": "Vacation!"
      },
      {
        "id": "e323fed5-6805-4bcf-8cb6-8b7a5014a9d9",
        "title": "Business Trip"
      }
    ],
    "findTrips": [
      {
        "id": "2c494055-78bc-430c-9ab7-19817f3fc060",
        "title": "Vacation!"
      }
    ]
  }
}

As you can see in the results, each field’s results gets its own field in the JSON output, keyed by the GraphQL field’s name.

Making the Same Query Over and Over and Over

Since the JSON output is organized by field name, we cannot query the same field twice by default:

query allAndFind($search:String!,$search2:String!) {
  findTrips(searchFor:$search) {
    id
    title
  }
  findTrips(searchFor:$search2) {
    id
    title
  }
}

If you try this, you will get an error back:

{
  "errors": [
    {
      "message": "Fields \"findTrips\" conflict because they have differing arguments. Use different aliases on the fields to fetch both if this was intentional.",
      "locations": [
        {
          "line": 2,
          "column": 3
        },
        {
          "line": 6,
          "column": 3
        }
      ]
    }
  ]
}

The error suggests the solution: aliases. By adding unique aliases to the fields, you provide unique keys for the JSON output, and GraphQL is happy:

query allAndFind($search:String!,$search2:String!) {
  find: findTrips(searchFor:$search) {
    id
    title
  }
  find2: findTrips(searchFor:$search2) {
    id
    title
  }
}

Given variables like:

{
  "search": "ca",
  "search2": "foo"
}

…we get results like:

{
  "data": {
    "find": [
      {
        "id": "2c494055-78bc-430c-9ab7-19817f3fc060",
        "title": "Vacation!"
      }
    ],
    "find2": []
  }
}

Mutating N Items

You can use the same approach to perform multiple mutations in a single operation. As with multiple queries, you are welcome to mutate one or more fields in an operation. If you wish to mutate the same field — such as inserting multiple objects — you can use aliases to have each result be identified separately in the GraphQL response.

For example, you could have this GraphQL operation:

mutation addTwo($trip1: TripInput!, $trip2: TripInput!) {
  tripOne: createTrip(trip: $trip1) {
    id
  }
  tripTwo: createTrip(trip: $trip2) {
    id
  }
}

Here, we insert two trips, using two TripInput objects:

{
  "trip1": {
    "title": "Foo",
    "priority": "OMG",
    "startTime": "2018-05-10",
    "duration": 10000
  },
  "trip2": {
    "title": "Bar",
    "priority": "MEDIUM",
    "startTime": "2018-07-11",
    "duration": 24000
  }
}

We then get back the IDs of the two newly-created trips:

{
  "data": {
    "tripOne": {
      "id": "62f92a4e-96f5-4207-b5c9-885e0cb4f3ad"
    },
    "tripTwo": {
      "id": "95d50515-20cd-45c2-ad5f-423ca756c9c3"
    }
  }
}

Aliases with Apollo-Android

The preview of this section apparently resembled a Pokémon.

GraphQL Execution Rules

The preview of this section is unavailable right now, but if you leave your name and number at the sound of the tone, it might get back to you (BEEEEEEEEEEEEP!).