Graphql queries: Difference between revisions

From wikinotes
 
(21 intermediate revisions by the same user not shown)
Line 1: Line 1:
Queries retrieve information without causing side-effects.
= Basics =
= Basics =
<blockquote>
<blockquote>
Graphql objects are arranged in a [https://en.wikipedia.org/wiki/Directed_acyclic_graph DAG].<br>
Top-level nodes can be queried directly,<br>
other objects are accessed through fields on top-level items,
optionally passing through an arbitrary number of child node-fields.
Queries are issued as POST requests with a [[json]] object as the payload.
<syntaxhighlight lang="bash">
curl -X POST \
  -H 'Content-Type: application/json' \
  -d '{"query":    "query queryMembers($search: String){ members(search: $search){ firstName lastName } }", \
      "variables" { "search": "al*" }}' \
  example.com/graphql
</syntaxhighlight>


Most of the time you'll just work with the query language.
<syntaxhighlight lang="python">
query {
  members($search: String){
    firstName
    lastName
  }
}
</syntaxhighlight>
And optionally JSON variables
<syntaxhighlight lang="javascript">
{ "search": "al*" }
</syntaxhighlight>
</blockquote><!-- Basics -->
</blockquote><!-- Basics -->


= Without Params =
= Without Params =
<blockquote>
<blockquote>
Some fields may be implied by the REST API path, so no params are required.
Some fields may be implied by the REST API path, so no params are required.<br>
<syntaxhighlight lang="graphql">
This URL probably refers to project 1.
 
<syntaxhighlight lang="python">
# https://tracking-system/projects/1/graphql
# https://tracking-system/projects/1/graphql
{
{
Line 19: Line 50:
= With Params =
= With Params =
<blockquote>
<blockquote>
Other times, you may need to use parameters in your query.
Other times, you may need to use parameters in your query.<br>
<syntaxhighlight lang="graphql">
The value passed to each parameter can be hard-coded, or provided in a JSON object.
# https://tracking-system/projects/1/graphql
 
{
 
   tasks($name: String){
In Schema
    status
<syntaxhighlight lang="python">
     createdAt
type Query {
  }
   task(name: String!): Task!
}
 
type Task {
  name:  String!
  status: String!
  id:     ID!
}
}
</syntaxhighlight>
</syntaxhighlight>


<syntaxhighlight lang="json">
In Request
{"name": "clean bathroom"}
<syntaxhighlight lang="python">
# hard-coded param
curl -X POST \
  -H 'Content-Type: application/json' \
  -d '{"query": "\
        { \
          task(name: "foo") { \
            status \
          } \
        }"' \
  https://domain.com/graphql
 
# param values can also be assigned in a JSON object
# (query's 'getTasks' name here is totally arbitrary, name as you please)
curl -X POST \
  -H 'Content-Type: application/json' \
  -d '{ \
        "query": "\
            query getTasks($name: String){ \
              task(name: $name) { \
                status \
              } \
            }",
        "variables": {"name": "foo"} \
      }' \
  https://domain.com/graphql
</syntaxhighlight>
</syntaxhighlight>
</blockquote><!-- With Params -->
</blockquote><!-- With Params -->
Line 37: Line 99:
= Fragments =
= Fragments =
<blockquote>
<blockquote>
{{ TODO |
Fragments are a named group of fields to select on a specific object-type.<br>
Example schema }}
Fragments let you:


* Select type-specific fields in heterogenous collections
* Select type-specific fields in heterogenous collections
* Concisely describe a group of fields, DRY out queries
* Concisely describe a group of fields, DRY out queries
* Concisely describe Recursive/Nested nodes
* Concisely describe Recursive/Nested nodes
{{ TODO |
Example schema }}


named fragments
named fragments
<syntaxhighlight lang="graphql">
<syntaxhighlight lang="python">
{
{
   children {
   children {
Line 72: Line 137:


inline fragments
inline fragments
<syntaxhighlight lang="graphql">
<syntaxhighlight lang="python">
{
{
   rentalInventory {
   rentalInventory {
Line 92: Line 157:
</syntaxhighlight>
</syntaxhighlight>
</blockquote><!-- Fragments -->
</blockquote><!-- Fragments -->
= Connections/Edges =
<blockquote>
</blockquote><!-- Connections/Edges -->
= Directives =
<blockquote>
Directives are conditionals. You can select fields if a boolean expression evaluates to true.
https://graphql.org/learn/queries/#directives
<syntaxhighlight lang="python">
@include(if: Boolean)
@skip(if: Boolean)
</syntaxhighlight>
</blockquote><!-- Directives -->
= Introspection =
<blockquote>
== List Types ==
<source lang="bash">
{ __schema { types { name } } }                  # list all types
{ __schema { mutationType { fields { name } } } }  # list all mutations
{ __schema { queryType { fields { name } } } }    # list all queries
</source>
== Query Available Fields ==
<source lang="bash">
{
  __type(name: "Droid") {  # GraphQL type we want fields from
    name
    fields {
      name
      type {
        name
        kind
      }
    }
  }
}
</source>
Returns all fields, and their type info.
== Query Type info ==
<source lang="bash">
{
  __type(name: "Shop") {
    fields {
      name
      description
    }
  }
}
</source>
</blockquote><!-- Introspection -->

Latest revision as of 17:23, 4 September 2021

Queries retrieve information without causing side-effects.

Basics

Graphql objects are arranged in a DAG.
Top-level nodes can be queried directly,
other objects are accessed through fields on top-level items, optionally passing through an arbitrary number of child node-fields.

Queries are issued as POST requests with a json object as the payload.

curl -X POST \
  -H 'Content-Type: application/json' \
  -d '{"query":    "query queryMembers($search: String){ members(search: $search){ firstName lastName } }", \
       "variables" { "search": "al*" }}' \
  example.com/graphql

Most of the time you'll just work with the query language.

query {
  members($search: String){
    firstName
    lastName
  }
}

And optionally JSON variables

{ "search": "al*" }

Without Params

Some fields may be implied by the REST API path, so no params are required.
This URL probably refers to project 1.

# https://tracking-system/projects/1/graphql
{
  name
  createdAt
}

With Params

Other times, you may need to use parameters in your query.
The value passed to each parameter can be hard-coded, or provided in a JSON object.


In Schema

type Query {
  task(name: String!): Task!
}

type Task {
  name:   String!
  status: String!
  id:     ID!
}

In Request

# hard-coded param
curl -X POST \
  -H 'Content-Type: application/json' \
  -d '{"query": "\
        { \
          task(name: "foo") { \
            status \
          } \
        }"' \
  https://domain.com/graphql

# param values can also be assigned in a JSON object
# (query's 'getTasks' name here is totally arbitrary, name as you please)
curl -X POST \
  -H 'Content-Type: application/json' \
  -d '{ \
        "query": "\
            query getTasks($name: String){ \
              task(name: $name) { \
                status \
              } \
            }",
         "variables": {"name": "foo"} \
       }' \
  https://domain.com/graphql

Fragments

Fragments are a named group of fields to select on a specific object-type.
Fragments let you:

  • Select type-specific fields in heterogenous collections
  • Concisely describe a group of fields, DRY out queries
  • Concisely describe Recursive/Nested nodes

TODO:

Example schema

named fragments

{
  children {

    ...nodeFields
    children {

      ...nodeFields {
        children {

          ...nodeFields
        }
      }
    }
  }
}


fragment nodeFields on Node {
  id
  text
  colour
  background-colour
}

inline fragments

{
  rentalInventory {
    vehicles {
      wheels               # select on both Car and Motorcycle
      passengers

      ... on Car {         # select on Car items only
        numSeatbelts
        numAirbags
      }

      ... on Motorcycle {  # select on Motorcycle items only
        numSaddleBags
      }
    }
  }
}

Connections/Edges

Directives

Directives are conditionals. You can select fields if a boolean expression evaluates to true. https://graphql.org/learn/queries/#directives

@include(if: Boolean)
@skip(if: Boolean)

Introspection

List Types

{ __schema { types { name } } }                   # list all types
{ __schema { mutationType { fields { name } } } }  # list all mutations
{ __schema { queryType { fields { name } } } }     # list all queries

Query Available Fields

{
  __type(name: "Droid") {  # GraphQL type we want fields from
    name
    fields {
      name
      type {
        name
        kind
      }
    }
  }
}

Returns all fields, and their type info.

Query Type info

{
  __type(name: "Shop") {
    fields {
      name
      description
    }
  }
}