The following is the first few sections of a chapter from GraphQL and Android, plus headings for the remaining major sections, to give you an idea about the content of the chapter.

Arguments and Variables

The GraphQL that we have used for most of this book has been fairly simplistic. We ask for some fields, and we get those results. We have not even performed a mutation yet.

Partly, that is due to a lack of input.

The GraphQL operations that we have seen mostly have been just a tree of fields. The user provided no input for any of it.

However, we did see one operation where we provided some input:

query find($search: String!) {
  findTrips(searchFor: $search) {
    id title startTime priority duration

Here, we are attempting to find trips based upon some supplied search criteria.

This input comes in the form of arguments (searchFor) and variables ($search). For any serious GraphQL work, you are going to use arguments and variables quite a bit. So, in this chapter, we will take a look at how these work, and along the way examine a new data type that we skipped over in the last chapter: the input object.


When you read the word “field” in the previous chapter, you probably were thinking about fields the way normal programmers do.

GraphQL is not normal.

A normal programmer would think that fields are…, well, fields. They are data. So, for example, the Trip might be a Java POJO akin to the one that Apollo-Android code-generates for us, with String id and String title fields.

This is entirely possible with GraphQL. However, fields can also be more like methods or functions, taking arguments.

This is fairly easy to envision with root fields, as we have done that already in this book, with the findTrips() root field on the Query object:

query find {
  findTrips(searchFor: "ca") {

Here, rather than retrieving all trips, we are finding trips that have ca somewhere in the title or notes. This makes findTrips() feel more like a Java method:

public class Query {
  List<Trip> findTrips(String searchFor) {
    // do cool stuff here to return results

It is also possible to do this with nested fields, but that is a bit esoteric, so we will hold off on that topic until later in the book.

Argument Data Types and Input Objects

Most of the data types described in the preceding chapter are valid data types for arguments. Specifically, all of the scalars (numbers, strings, ID, enums) are fine, as are lists of those. And, arguments can be marked as non-null, indicating that the argument is required.

What is not supported are object types (e.g., Trip) or things closely tied to object types, like unions (e.g., Note) and interfaces (e.g., Plan). Those can serve as output, but not input.

To help make up the gap, GraphQL has the concept of an “input object”. This is another data type, closely resembling a regular object type. However, it only supports scalars or other input objects as fields.

The GraphQL schema shown earlier had one of these, one that we just ignored at the time:

  input TripInput {
    startTime: String!
    title: String!
    priority: Priority!
    duration: Int!

TripInput contains a few of the fields from Trip. However, technically, Trip and TripInput are unrelated, in terms of the schema. TripInput is only used in the createTrip() field on the Mutation object:

  type Mutation {
    createTrip(trip: TripInput!): Trip!

It so happens that createTrip() takes the data from the supplied TripInput and creates a Trip. However, that is business logic implemented in the JavaScript that handles operations with createTrip() — there is nothing in the schema itself that says that TripInput has anything to do with Trip.

Mostly, using input objects is a way to shrink the argument list for a field. createTrip() could just as easily request a bunch of arguments, reflecting the fields that we happen to define on TripInput, rather than accepting a TripInput. Particularly for arguments that are logically peers of one another — such as fields that all go directly into a new Trip – using an input object will be a useful design pattern, but it is merely a pattern, not a requirement.

Argument Patterns

A number of common Web service API patterns can be implemented via arguments on root fields, such as those outlined in the following sections. This is not a comprehensive list of such patterns, let alone all possible ways of using arguments, but they should give you an idea of the role that arguments play.

Searching and Sorting

The searchFor argument is a crude, but simple, way of expressing a search request. The client has no means of indicating where we should be using that search term, or even how the search term should be used. That is up to the server, and it is up to the developers of the server to document the rules. The searchFor value could be interpreted in its own language, akin to how search engines, SQLite’s FTS3/FTS4 tables, and the like use boolean algebra as part of interpreting what you supply as a search expression.

It is also possible to offer richer syntax for searching directly in the GraphQL itself. For example, we could have an input object that mirrors likely fields on Trip that allow us to provide search expressions for those specific fields (or null as a wildcard, accepting anything):

input TripSearchCriteria {
  title: String,
  notes: String,
  priority: Priority,
  minDuration: Int,
  maxDuration: Int

A searchTrips() field could take a TripSearchCriteria as input and apply the individual fields from those criteria (e.g., restricting results to trips with a duration in the specified range, if either or both of minDuration and maxDuration were supplied).

The expressive power available to the client is dictated by what the server wants to support. The CRUD store offers a GraphQL interface to its database, one that code-generates a GraphQL schema supporting expansive searching/filtering criteria:

query find {
    filter: {
      OR: [
          AND: [
              startDate_gte: "2017"
              title_starts_with: "Vacation"
          priority: "OMG"
  ) {
    id title

Here, we would be retrieving any trip where the priority is OMG or the title starts with Vacation and is in 2017 or beyond.

Similarly, the GraphQL schema might support arguments for server-side sorting of the results (e.g., a sortBy argument taking the name of a field).


With REST-style Web services, updates to resources are handled via particular HTTP actions (PUT, PATCH, etc.), with the content representing the update coming in the HTTP request body.

With GraphQL, updates to resources are handled by mutations, with the content representing the update coming in the arguments. For example, this could be in the form of an input object, so there is a single argument to the insert() mutation (with the content to be inserted), or two arguments to an replace() (with the second being the unique identifier of the content to be replaced).

We will see some CRUD later in this chapter.


Many Web service APIs work off of a “page-at-a-time” metaphor, as asking for the entire data set might be too much for either the client or the server. Classic implementations include:

Using Arguments in Android

The Trips/CW/SearchArgs sample project adds a SearchView to the DynamicList sample from the chapter on dynamic GraphQL. When the user searches on something, we will use findTrips() to find the subset of trips that match the search expression, then show that subset in the list.

So, we have a menu resource with our SearchView:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="">



That, in turn, is set up in query mode, with the submit button enabled, in onCreateOptionsMenu() of our SimpleTripsFragment:

  public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(, menu);



    super.onCreateOptionsMenu(menu, inflater);

When the user clicks that submit button in the SearchView, we ask the MainActivity to search for the requested search expression:

  public boolean onQueryTextSubmit(String query) {


That, in turn, creates a new SimpleTripsFragment, using a new searchFor() factory method, and adds that new fragment to the back stack:

  void searchFor(String search) {

searchFor() on SimpleTripsFragment just stuffs the search expression into the arguments Bundle:

  public static SimpleTripsFragment searchFor(String search) {
    SimpleTripsFragment result=new SimpleTripsFragment();
    Bundle args=new Bundle();

    args.putString(ARG_SEARCH, search);


In onCreate() of SimpleTripsFragment, we still set up our Observable. However, now, we see if we have a search expression, and we choose different sources of data based on that, calling either the original query() method or a new search() method:

  public void onCreate(Bundle savedInstanceState) {


    final String searchFor=getSearchExpression();

      .defer(new Callable<ObservableSource<GraphQLResponse>>() {
        public ObservableSource<GraphQLResponse> call() throws Exception {
          return(Observable.just(searchFor==null ? query() : search(searchFor)));

Using arguments without variables is… annoying, at best. We have to use string interpolation, replacing placeholders with our desired search expression, and hope for the best. That is only possible using dynamic GraphQL — code generators do not expose the GraphQL source for you to massage this way.

So, we have a SEARCH_DOCUMENT with our dynamic GraphQL, with a %s placeholder for the searchFor argument value:

  private static final String SEARCH_DOCUMENT=
    "{ findTrips(searchFor: \"%s\") { id title startTime priority duration creationTime } }";

search() then uses String.format() to add the search expression to the GraphQL document:

  private GraphQLResponse search(String search) throws IOException {
    HashMap<String, Object> payload=new HashMap<>();
    Gson gson=new Gson();
    String query=String.format(SEARCH_DOCUMENT, search);

    payload.put(QUERY, query);

    String body=gson.toJson(payload);
    Request request=new Request.Builder()
      .post(RequestBody.create(MEDIA_TYPE_JSON, body))
    Response okResponse=new OkHttpClient().newCall(request).execute();

    return(gson.fromJson(okResponse.body().charStream(), GraphQLResponse.class));

The revised app now has a SearchView, initially collapsed into an icon:

SearchArgs Demo App, As Initially Launched
Figure 27: SearchArgs Demo App, As Initially Launched

Tapping the icon opens up the SearchView proper, where you can type in a search expression:

SearchArgs Demo App, with Search Expression
Figure 28: SearchArgs Demo App, with Search Expression

Submitting that SearchView (click the rightward-pointing caret) brings up a list of the search results:

SearchArgs Demo App, with Search Results
Figure 29: SearchArgs Demo App, with Search Results


The preview of this section is [REDACTED].

Variables in Android

The preview of this section was lost in the sofa cushions.

A Little Bit of CRUD

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