# Client‐specified queries

> Through its type system, a GraphQL server publishes the capabilities that its clients
  are allowed to consume. It is the client that is responsible for specifying exactly how it will consume those
  published capabilities. These queries are specified at field‐level granularity. In the majority of client‐server 
  applications written without GraphQL, the server determines the data returned in its various scripted endpoints.
  A GraphQL query, on the other hand, returns exactly what a client asks for and no more.

See the [GraphQL specification](https://spec.graphql.org/June2018/) for more details.

What, exactly, does this mean, and why should I care? Well, in a traditional REST-based service you may have an endpoint
which returns something like the following when you request a `Song`:

```url
GET /song?isrc=QM4TW2003053
Content-Type: application/json
```

```json
{
  "isrc": "QM4TW2003053",
  "name": "Hold Your Hand",
  "artist_id": 1465654,
  "product_id": 2761914
}
```

Teams may find that they have use cases to extend what is returned by this endpoint, and there may be several 
new features that require expansion of this endpoint in new directions. Let's say that one team working at The Orchard 
has a use case where they wish to retrieve a count of streams over the past 7 days for a `Song`.

```json
{
  "isrc": "QM4TW2003053",
  "name": "Hold Your Hand",
  "artist_id": 1465654,
  "product_id": 2761914,
  "streams": [
    { "date": "2020-11-02T15:20:12-05:00", "streams": 324234 },
    { "date": "2020-11-01T15:20:12-05:00", "streams": 94234 },
    { "date": "2020-10-31T15:20:12-05:00", "streams": 104422 },
    { "date": "2020-10-30T15:20:12-05:00", "streams": 2342 },
    { "date": "2020-10-29T15:20:12-05:00", "streams": 34744 },
    { "date": "2020-10-28T15:20:12-05:00", "streams": 23463 },
    { "date": "2020-10-27T15:20:12-05:00", "streams": 9543 }
  ] 
}
```

Meanwhile, another team concerned with revenue may somehow be able to determine the monetary payout for the `Song` over
the past 7 days, and expand the endpoint to return this information as well:

```json
{
  "isrc": "QM4TW2003053",
  "name": "Hold Your Hand",
  "artist_id": 1465654,
  "product_id": 2761914,
  "streams": [
    { "date": "2020-11-02T15:20:12-05:00", "value": 324234 },
    { "date": "2020-11-01T15:20:12-05:00", "value": 94234 },
    { "date": "2020-10-31T15:20:12-05:00", "value": 104422 },
    { "date": "2020-10-30T15:20:12-05:00", "value": 2342 },
    { "date": "2020-10-29T15:20:12-05:00", "value": 34744 },
    { "date": "2020-10-28T15:20:12-05:00", "value": 23463 },
    { "date": "2020-10-27T15:20:12-05:00", "value": 9543 }
  ],
  "revenue": {
    "currency": "USD",
    "value": 32
  }
}
```

Suppose that both the streaming and revenue data are both, for some reason, computationally expensive to retrieve. 
Maybe the database isn't indexed to properly optimize joins on a streams table, or tallying up revenue for the past 7
days involves performing an aggregation over thousands of records. In this case, a previously quick REST request to
retrieve this data is going to be significatly slower with the addition of this data.

One way to address this problem would be to split this up into 3 separate endpoints -- one for metadata information 
related to the song, another for streaming data, and a third for revenue calculations. This is probably not a bad idea,
and in fact these are very different concerns that would generally make sense to be implemented in microservices with
concerns related to each aspect of the `Song`'s data. So now we might have three new requests:

```url
GET https://ows-metadata-prod.theorchard.io/song/QM4TW2003053
```
```url
GET https://ows-analytics-prod.theorchard.io/song/QM4TW2003053
```
```url
GET https://ows-finance-prod.theorchard.io/song/QM4TW2003053
```

But what happens to a client, say Orchard Insights, that would want to display all this information on the same page at
the same time? The client would need to make 3 separate requests, and then stitch the data back together so that it
could be displayed in a cohesive view. What if OrchardGo wants to retrieve `Song` metadata and streaming data, but not
financial data? Now this client needs to stitch together the result of 2 separate requests.

GraphQL resolves this issue by allowing you to craft queries that know _how_ each of these facets of a `Song` can be
retrieved, as well as allowing you to specify _which_ facets you would like.

In our example case of Insights, you could write a GraphQL query to retrieve all the data at once, which would look 
something like:

```graphql
query {
  song(isrc: "QM4TW2003053") {
    isrc
    name
    streams {
      date
      value
    }
    revenue {
      currency
      value
    }
  }
}
```

You could also write a query for OrchardGo which uses only metadata and streaming information that would look like:

```graphql
query {
  song(isrc: "QM4TW2003053") {
    isrc
    name
    streams {
      date
      value
    }
  }
}
```

Since GraphQL knows how to resolve each of these subgraphs, the logic to populate their data can be reused without
the client logic being changed or updated.

Now let's say there's a design requirement that metadata, streaming information, and revenue can all be loaded in
separate sections of a webpage, each with their independent loading states, something like:

```
+------------------------------------------------------+
|                   Song Metadata                      |
+------------------------------------------------------+
+-------------------------+  +-------------------------+
|  Streaming Performance  |  |         Revenue         |
+-------------------------+  +-------------------------+
```

Our above request which retrieves all this data at once could be used prior to this requirement, but now the client can
ask for each piece of the `Song` individually without rewriting any of the backend logic:

```graphql
query {
  song(isrc: "QM4TW2003053") {
    isrc
    name
  }
}
```

```graphql
query {
  song(isrc: "QM4TW2003053") {
    streams {
      date
      value
    }
  }
}
```

```graphql
query {
  song(isrc: "QM4TW2003053") {
    revenue {
      currency
      value
    }
  }
}
```
