Current section
Files
Jump to
Current section
Files
lib/graphql/relay/connection.ex
defmodule GraphQL.Relay.Connection do
@doc """
Any type whose name ends in "Connection" is considered by Relay to be a
Connection Type. Connection types must be an "Object" as defined in the
"Type System" section of the GraphQL Specification.
Connection types must have fields named edges and pageInfo. They may have
additional fields related to the connection, as the schema designer sees fit.
https://facebook.github.io/relay/graphql/connections.htm#sec-Connection-Types
"""
alias GraphQL.Type.Boolean
alias GraphQL.Type.Int
alias GraphQL.Type.NonNull
alias GraphQL.Type.ObjectType
def new(config) do
node_type = config[:node_type]
name = config[:name] || Map.get(node_type, :name)
edge_fields = config[:edge_fields] || %{}
connection_fields = config[:connection_fields] || %{}
resolve_node = config[:resolve_node]
resolve_cursor = config[:resolve_cursor]
edge_type = %ObjectType{
name: "#{name}Edge",
description: "An edge in a connection.",
fields: Map.merge(GraphQL.Relay.resolve_maybe_thunk(edge_fields), %{
node: %{
type: node_type,
description: "The item at the end of the edge",
resolve: resolve_node
},
cursor: %{
type: %NonNull{ofType: %GraphQL.Type.String{}},
description: "A cursor for use in pagination",
resolve: resolve_cursor
}
})
}
connection_type = %ObjectType{
name: "#{name}Connection",
description: "A connection to a list of items.",
fields: Map.merge(GraphQL.Relay.resolve_maybe_thunk(connection_fields), %{
edges: %{
type: %GraphQL.Type.List{ofType: edge_type},
description: "Information to aid in pagination."
},
pageInfo: %{
type: %NonNull{ofType: page_info},
description: "Information to aid in pagination."
},
})
}
connection_type
end
def args(additional_args \\ %{}) do
Map.merge(forward_args, backward_args)
|> Map.merge(additional_args)
end
def forward_args do
%{
"after": %{type: %GraphQL.Type.String{}},
first: %{type: %Int{}}
}
end
def backward_args do
%{
before: %{type: %GraphQL.Type.String{}},
last: %{type: %Int{}}
}
end
def page_info do
%ObjectType{
name: "PageInfo",
description: "Information about pagination in a connection.",
fields: %{
hasNextPage: %{
type: %NonNull{ofType: %Boolean{}},
description: "When paginating forwards, are there more items?"
},
hasPreviousPage: %{
type: %NonNull{ofType: %Boolean{}},
description: "When paginating backwards, are there more items?"
},
startCursor: %{
type: %GraphQL.Type.String{},
description: "When paginating backwards, the cursor to continue."
},
endCursor: %{
type: %GraphQL.Type.String{},
description: "When paginating forwards, the cursor to continue."
}
}
}
end
end