GraphQL Query Cheatsheet
View SourceThis cheatsheet provides quick reference for the basic and common GraphqlQuery usage.
use GraphqlQuery
Basic Usage
defmodule MyApp.Queries do
use GraphqlQuery
# You have access to ~GQL sigil and other macros
end
With Options
defmodule MyApp.Queries do
use GraphqlQuery,
schema: MyApp.Schema,
runtime: false,
ignore: false,
evaluate: false,
fragments: [],
format: false
end
use GraphqlQuery.Schema
Load schema from a graphql file
schema.ex
defmodule MyApp.Schema do
use GraphqlQuery.Schema,
schema_path: "priv/schema.graphql"
end
priv/schema.graphql
schema {
query: RootQueryType
}
"An item"
type Item {
id: ID
name: String
}
type RootQueryType {
item(id: ID!): Item
}
Manual schema module
defmodule MyApp.Schema do
use GraphqlQuery.Schema
@impl GraphqlQuery.Schema
def schema do
# Suffix "s" to parse as schema
~GQL""s
end
# Optional: By default is this module's file path
# Can be nil, or a string. It's used for validation errors
@impl GraphqlQuery.Schema
def schema_path, do: nil
end
Load schema from an Absinthe schema
schema.ex
defmodule MyApp.Schema do
use GraphqlQuery.Schema, absinthe_schema: MyAppWeb.Graphql.Schema
end
my_app_web/graphql/schema.ex
defmodule MyAppWeb.Graphql.Schema do
use Absinthe.Schema
@desc "An item"
object :item do
field(:id, :id)
field(:name, :string)
end
query do
field :item, :item do
arg(:id, non_null(:id))
resolve(&Resolvers.resolve_item/3)
end
end
end
~GQL Sigil
Queries
~GQL"""
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}
"""
Fragments
~GQL"""
fragment UserFields on User {
id
name
email
}
"""f # <- Important the "f" option
Mutation
~GQL"""
mutation CreateUser($input: UserInput!) {
createUser(input: $input) {
id
name
}
}
"""
Schema Definitions
~GQL"""
type User {
id: ID!
name: String!
email: String!
}
type Query {
user(id: ID!): User
}
"""s # <- Important the "s" option
Sigil Modifiers
# Ignore validation warnings
~GQL""i
# Runtime validation
~GQL""r
# Query document (default)
~GQL""q
# Fragment document
~GQL""f
# Schema document
~GQL""s
Validate with Schema
defmodule MyApp.Queries do
use GraphqlQuery, schema: MyApp.Schema
def get_user do
~GQL"""
query GetUser($id: ID!) {
user(id: $id) {
id
name
}
}
"""
end
end
gql_from_file
Basic File Loading
# Load query from file
query = gql_from_file("priv/queries/get_user.graphql")
Other Options
# Load fragment from file
fragment = gql_from_file("priv/fragments/user.gql", type: :fragment)
# Load schema from file
schema = gql_from_file("priv/schema.graphql", type: :schema)
# Validate with a schema
fragment = gql_from_file("priv/fragments/user.gql", schema: MyApp.Schema)
# Add fragments
fragment = gql_from_file("priv/fragments/user.gql", fragments: [@fragments])
# Skip validation
query = gql_from_file("priv/queries/get_user.graphql", ignore: true)
# Runtime validation
query = gql_from_file("priv/queries/get_user.graphql", runtime: true)
# Apply formatting when transformed to string
query = gql_from_file("priv/queries/get_user.graphql", format: true)
document_with_options
With ~GQL sigil to validate with schema
document_with_options schema: MySchema do
~GQL"""
query GetUser { user { ...UserFragment } }
"""
end
With ~GQL sigil to add fragments
@user_fragment ~GQL"""
fragment UserFields on User {
id
name
email
}
"""f
document_with_options fragments: [@user_fragment] do
~GQL"""
query GetUserWithFragment {
user {
...UserFields
}
}
"""
end
gql Macro
With string interpolation
# Used only when you need to interpolate data
# But it's prefered to use variables and fragments
@fields "id name email"
query = gql "query { user { #{@fields} } }"
With Options
# With schema validation
query = gql [schema: MyApp.Schema], ""
# With fragments
query = gql [fragments: [@user_fragment]], ""
# Skip validation
query = gql [ignore: true], ""
# Runtime validation
query = gql [runtime: true], ""
# Apply automatic formatting when transforming to string
query = gql [format: true], "query{user{id name}}"
Dynamic Content
# Useful for testing if you want to build a query with dynamic fields
def build_user_query(field_list) do
fields = Enum.join(field_list)
gql [runtime: true], "query { user { #{fields} }"
end
With Module Schema
defmodule MyApp.Queries do
use GraphqlQuery, schema: MyApp.Schema
def build_query(fields) do
gql "query { user { #{fields} } }"
end
end
JSON encoding
With Jason
# All macros return a GraphqlDocument struct that implements Jason.Encoder
query = ~GQL"..."
Jason.encode!(query)
# {"query": "...", "variables": {}}
# You can add fragments or variables!
query
|> GraphqlQuery.Document.add_fragment(fragment)
|> GraphqlQuery.Document.add_variables(id: 123, sort: :ASC)
|> Jason.encode!()
# {"query": "... with fragment if used", "variables": {"id": 123, "sort": "ASC"}}
With JSON (Elixir >= 1.18)
# Just like Jason, it implements JSON.Encoder too and support the same features
query = ~GQL"..."
JSON.encode!(query)
# {"query": "...", "variables": {}}
to_string
Transform a document to string
# GraphqlQuery.Document and GraphqlQuery.Fragment implements `to_string`, so you can do:
# it returns the query with the needed fragments
query = ~GQL"..."
to_string(query)
"#{query}"
Format when doing to_string
# GQL sigil content is formatted automatically with mix format
# But other macros are not, if you want to format the content when
# doing to_string, you have the `format` option
# this is useful specially on testing
query = gql [format: true], ""
fragment = gql_from_document "", [format: true]
# Now it will format the content correctly!
to_string(query)
"#{fragment}"
# Even when encoding to JSON
Jason.encode!(query)
Full example!
schema.ex
defmodule Schema do
use GraphqlQuery.Schema, schema_path: "priv/schema.graphql"
end
fragments.ex
defmodule Fragments do
use GraphqlQuery, schema: Schema
def user_fragment do
~GQL"""
fragment UserFragment on User {
id
name
email
}
"""f
end
def company_fragment do
~GQL"""
fragment CompanyFragment on Company {
id
name
}
"""f
end
end
priv/queries/get_user_with_company_by_id.graphql
query GetUserById($id: ID!) {
user(id: $id) {
...UserFragment
company {
...CompanyFragment
}
}
}
queries.ex
defmodule Queries do
# The library is smart and will only add used fragments to the final query
use GraphqlQuery, schema: Schema, fragments: [Fragments.user_fragment(), Fragments.company_fragment()]
def user_by_id do
~GQL"""
query GetUserById($id: ID!) {
user(id: $id) {
...UserFragment
}
}
"""
end
def user_and_company_by_id do
gql_from_file "priv/queries/get_user_with_company_by_id.graphql"
end
@post_fragment ~GQL"""
fragment PostFragment on Post {
id
title
content
}
"""f
def user_posts do
# You can override the available fragments to one specific query
document_with_options fragments: [@post_fragment] do
~GQL"""
query UserPosts($id: ID!) {
posts {
...PostFragment
}
}
"""
end
end
end
requests.ex
defmodule Requests do
alias GraphqlQuery.Document
def user_by_id(user_id) do
query = Queries.user_by_id() |> Document.add_variables(id: user_id)
Req.post!("/graphql", json: query)
end
def user_and_company_by_id(user_id) do
query = Queries.user_and_company_by_id() |> Document.add_variables(id: user_id)
Req.post!("/graphql", json: query)
end
def user_posts(user_id) do
query = Queries.user_posts() |> Document.add_variables(id: user_id)
Req.post!("/graphql", json: query)
end
end