Graphql queries: Difference between revisions

From wikinotes
 
(18 intermediate revisions by the same user not shown)
Line 1: Line 1:
Queries retrieve information without causing side-effects.
= Basics =
= Basics =
<blockquote>
<blockquote>
Line 6: Line 8:
optionally passing through an arbitrary number of child node-fields.
optionally passing through an arbitrary number of child node-fields.


<syntaxhighlight lang="graphql">
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>
</syntaxhighlight>


<syntaxhighlight lang="graphql">
Most of the time you'll just work with the query language.
# select id/name fields on Project
<syntaxhighlight lang="python">
{
query {
   Project { # <-- a top-level node
   members($search: String){
     id      # <-- fields on that node
     firstName
     name
     lastName
   }
   }
}
}
</syntaxhighlight>
And optionally JSON variables
<syntaxhighlight lang="javascript">
{ "search": "al*" }
</syntaxhighlight>
</syntaxhighlight>
</blockquote><!-- Basics -->
</blockquote><!-- Basics -->
Line 23: Line 35:
= 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 36: 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 65: Line 110:


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


inline fragments
inline fragments
<syntaxhighlight lang="graphql">
<syntaxhighlight lang="python">
{
{
   rentalInventory {
   rentalInventory {
Line 112: 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
    }
  }
}