### Creating Connections from a Slice Source: https://context7_llms Shows an example of using `Absinthe.Relay.Connection.from_slice/3`. This function is used when you have already retrieved the exact items for the current connection request and need to format them into a connection object. ```elixir # In a Resolver module def list_teams(args, %{context: %{current_user: user}}) do TeamAssignment |> from |> where([a], a.user_id == ^user.id) |> join(:left, [a], t in assoc(a, :team)) |> select([a,t], {t, map(a, [:role])}) |> Relay.Connection.from_query(&Repo.all/1, args) end ``` -------------------------------- ### Creating Connections from a List Source: https://context7_llms Provides an example of using the `Absinthe.Relay.Connection.from_list/3` function to generate a connection object from an in-memory list of data. This is suitable when all items to be paginated are already available. ```elixir #in a resolver module @items ~w(foo bar baz) def list(args, _) do Connection.from_list(@items, args) end ``` -------------------------------- ### Basic Global ID Translator Example Source: https://context7_llms An example implementation of an ID Translator behavior. This translator encodes global IDs by concatenating the type name and source ID with a colon. It decodes them by splitting the string on the colon. This provides a simple, readable global ID format. ```elixir defmodule MyApp.Absinthe.IDTranslator do @behaviour Absinthe.Relay.Node.IDTranslator def to_global_id(type_name, source_id, _schema) do {:ok, "#{type_name}:#{source_id}"} end def from_global_id(global_id, _schema) do case String.split(global_id, ":", parts: 2) do [type_name, source_id] -> {:ok, type_name, source_id} _ -> {:error, "Could not extract value from ID `#{inspect global_id}`"} end end end ``` -------------------------------- ### Supplying Edge Information in Connections Source: https://context7_llms Illustrates how to add custom fields to the edge of a connection, allowing for extra information to be passed along with the node. This example defines a 'role' field on the edge for a user connection and shows how to format input data as tuples for this purpose. ```elixir connection node_type: :user do edge do field :role, :string end end ``` ```elixir [ {%{name: "Jim"}, role: "owner"}, {%{name: "Sari"}, role: "guest"}, {%{name: "Lee"}, %{role: "guest"}} # This is OK, too ] |> Connection.from_list(args) ``` -------------------------------- ### Absinthe.Relay.Connection.Notation.connection/2 - Customize Connection Object Source: https://context7_llms Demonstrates customizing the connection object for a Relay connection. This example adds a `total_age` field to the `:favorite_pets_connection` which calculates the sum of ages from the edges. It also shows how to use the `edge` macro within the connection block. ```elixir connection :favorite_pets, node_type: :pet do field :total_age, :float do resolve fn _, %{source: conn} -> sum = conn.edges |> Enum.map(fn edge -> edge.node.age) |> Enum.sum {:ok, sum} end end edge do # ... end end ``` -------------------------------- ### Define Classic Relay Schema with Absinthe Source: https://context7_llms Illustrates using Absinthe.Relay.Schema to define a classic Relay schema, compatible with versions prior to Relay v1.0. This is useful for maintaining compatibility with older Relay setups. ```elixir defmodule Schema do use Absinthe.Schema use Absinthe.Relay.Schema, :classic # ... end ``` -------------------------------- ### Define Paginated Connection Field for Pets Source: https://context7_llms Example of defining a 'pets' connection field within a 'person' object type using Absinthe.Relay.Connection. This enables paginating a list of associated pet records. ```elixir object :person do field :first_name, :string connection field :pets, node_type: :pet do resolve fn pagination_args, %{source: person} -> Absinthe.Relay.Connection.from_list( Enum.map(person.pet_ids, &pet_from_id(&1)), pagination_args ) end end end end ``` -------------------------------- ### Absinthe.Relay.Connection.Notation.edge/2 - Customize Edge Type Source: https://context7_llms Illustrates how to customize the edge type within a Relay connection definition. This example adds a `node_name_backwards` field to the edge that resolves to the reversed name of the node. ```elixir connection node_type: :pet do # ... edge do field :node_name_backwards, :string do resolve fn _, %{source: edge} -> {:ok, edge.node.name |> String.reverse} end end end end ``` -------------------------------- ### Define Relay Mutation Payload with Client Mutation ID using Absinthe Source: https://context7_llms Defines a complete GraphQL mutation with a single input and automatically includes a `clientMutationId`. This macro simplifies the setup for common mutation patterns in Relay. It takes the mutation name and a block defining the input and output fields. ```elixir defmodule MyAppWeb.Schema.Mutations do alias Absinthe.Relay.Mutation.Notation.Modern mutation do payload :create_user, :create_user_payload # ... input and resolve definitions end defp create_user_payload(result, _args) do result end end ``` -------------------------------- ### Define Node Interface/Field/Object with Absinthe.Relay.Node.Notation.node/2 Source: https://context7_llms A macro used to define node interface, field, or object types within an Absinthe schema. It simplifies the process of setting up Relay-compliant node definitions. Refer to the `Absinthe.Relay.Node` module documentation for detailed usage examples. ```elixir defmodule MyApp.Schema do use Absinthe.Schema import Absinthe.Relay.Node.Notation node field :user do # ... configuration for the user node end end ``` -------------------------------- ### Parse Single Node ID Argument with Absinthe.Relay.Node.ParseIDs Source: https://context7_llms Parses a single node (global) ID argument, such as `:item_id`, and replaces it with the application-specific ID. This middleware is useful for simplifying resolver logic by handling ID transformation upfront. The example shows how to configure it for a specific field. ```elixir field :item, :item do arg :item_id, non_null(:id) middleware Absinthe.Relay.Node.ParseIDs, item_id: :item resolve &item_resolver/3 end ``` -------------------------------- ### Creating Connections from an Ecto Query Source: https://context7_llms Demonstrates using `Absinthe.Relay.Connection.from_query/4` to build a connection directly from an Ecto query. This function automatically handles setting limit and offset on the query. It requires the query to have an `order_by` clause. ```elixir # In a PostResolver module alias Absinthe.Relay def list(args, %{context: %{current_user: user}}) do Post |> where(author_id: ^user.id) |> Relay.Connection.from_query(&Repo.all/1, args) end ``` -------------------------------- ### Absinthe.Relay.Connection.from_slice/3 - List Posts with Pagination Source: https://context7_llms Demonstrates how to use `Absinthe.Relay.Connection.from_slice/3` to fetch and paginate a list of posts for the current user. It calculates the limit and offset from arguments and applies them to a database query before converting the result into a connection. ```elixir alias Absinthe.Relay def list(args, %{context: %{current_user: user}}) do {:ok, :forward, limit} = Connection.limit(args) {:ok, offset} = Connection.offset(args) Post |> where(author_id: ^user.id) |> limit(^limit) |> offset(^offset) |> Repo.all |> Relay.Connection.from_slice(offset) end ``` -------------------------------- ### Apply ParseIDs Middleware Before Mutation Middleware Source: https://context7_llms Demonstrates how to correctly apply `Absinthe.Relay.Node.ParseIDs` middleware within a mutation payload when it needs to be executed before the `Absinthe.Relay.Mutation` middleware. This requires wrapping the ID parsing rules within an `:input` key to ensure proper argument handling. ```elixir def middleware(middleware, %Absinthe.Type.Field{identifier: :change_something}, _) do # Note the addition of the `input` level: [{Absinthe.Relay.Node.ParseIDs, input: [profile: [user_id: :user]]} | middleware] end def middleware(middleware, _, _) do middleware end ``` -------------------------------- ### GraphQL Query for Classic Relay Mutation Source: https://context7_llms A sample GraphQL mutation query document that targets the ':simple_mutation' field defined using Absinthe.Relay.Mutation.Notation.Classic. It includes the input data and demonstrates how to request the 'result' and 'clientMutationId' in the response. ```graphql mutation DoSomethingSimple { simpleMutation(input: {inputData: 2, clientMutationId: "abc"}) { result clientMutationId } } ``` -------------------------------- ### Absinthe.Relay.Connection.from_slice/3 Source: https://context7_llms Converts a slice of data into a Relay connection, similar to from_query/2 but without backwards pagination concerns. ```APIDOC ## GET /api/posts ### Description Retrieves a paginated list of posts for the current user. ### Method GET ### Endpoint /api/posts ### Query Parameters - **first** (Int) - Optional - The number of items to retrieve. - **after** (String) - Optional - A cursor for fetching items after a specific point. - **last** (Int) - Optional - The number of items to retrieve (for backwards pagination). - **before** (String) - Optional - A cursor for fetching items before a specific point. ### Request Example ```json { "first": 10, "after": "cursor_string" } ``` ### Response #### Success Response (200) - **data** (object) - Contains the connection data. - **edges** (array) - A list of edges, each containing a node. - **node** (object) - The actual data object (e.g., a Post). - **cursor** (string) - An opaque cursor for the edge. - **pageInfo** (object) - Information about the pagination. - **hasNextPage** (boolean) - Indicates if there are more pages. - **hasPreviousPage** (boolean) - Indicates if there are previous pages. - **startCursor** (string) - The cursor for the first item. - **endCursor** (string) - The cursor for the last item. #### Response Example ```json { "data": { "edges": [ { "node": { "id": "1", "title": "My First Post" }, "cursor": "cursor_string_1" } ], "pageInfo": { "hasNextPage": true, "hasPreviousPage": false, "startCursor": "cursor_string_1", "endCursor": "cursor_string_1" } } } ``` ``` -------------------------------- ### Define Modern Relay Schema with Absinthe Source: https://context7_llms Demonstrates how to use Absinthe.Relay.Schema to define a modern Relay-compliant schema. This approach is suitable for applications targeting Relay v1.0 and later. ```elixir defmodule Schema do use Absinthe.Schema use Absinthe.Relay.Schema, :modern # ... end ``` -------------------------------- ### Define Schema Notation for Relay Types Source: https://context7_llms Shows how to use Absinthe.Relay.Schema.Notation for defining type modules within a Relay schema. This is an alternative to using Absinthe.Relay.Schema directly for type definitions. ```elixir defmodule Schema do use Absinthe.Schema.Notation use Absinthe.Relay.Schema.Notation, :modern # ... end ``` -------------------------------- ### GraphQL Query for Modern Relay Mutation Source: https://context7_llms A sample GraphQL mutation query document for a mutation defined using Absinthe.Relay.Mutation.Notation.Modern. It demonstrates passing the 'inputData' and requesting the 'result'. Note the absence of 'clientMutationId' in the input, as it's not automatically handled by the modern notation. ```graphql mutation DoSomethingSimple { simpleMutation(input: {inputData: 2}) { result } } ``` -------------------------------- ### Absinthe.Relay.Mutation.Notation.Classic Source: https://context7_llms Provides support for Relay Classic mutations, including handling single input objects and client mutation IDs. ```APIDOC ## Relay Classic Mutations ### Description This module facilitates the implementation of Relay Classic mutations within Absinthe schemas. It supports mutations that accept a single input object and return a client mutation ID in the payload. ### Method Module ### Endpoint N/A (Schema definition) ### Parameters N/A ### Request Example Refer to Relay Classic mutation documentation for specific examples. ### Response N/A ``` -------------------------------- ### Define Connection Field with Custom Arguments Source: https://context7_llms Demonstrates how to add custom pagination arguments to a Relay connection field. This allows for more flexible querying beyond the standard pagination parameters. ```elixir connection field :pets, node_type: :pet do arg :custom_arg, :custom # other args... resolve fn pagination_args_and_custom_args, %{source: person} -> # ... return {:ok, a_connection} end end ``` -------------------------------- ### Apply ParseIDs Middleware After Mutation Middleware Source: https://context7_llms Illustrates an alternative configuration for applying `Absinthe.Relay.Node.ParseIDs` middleware within a mutation payload, where it is executed after the `Absinthe.Relay.Mutation` middleware. In this scenario, the wrapping `:input` key is not needed, simplifying the middleware configuration. ```elixir def middleware(middleware, %Absinthe.Type.Field{identifier: :change_something}, _) do # No `input` wrapper needed when applied after Absinthe.Relay.Mutation [{Absinthe.Relay.Node.ParseIDs, profile: [user_id: :user]} | middleware] end def middleware(middleware, _, _) do middleware end ``` -------------------------------- ### Customizing Node Resolution for Connections Source: https://context7_llms Demonstrates how to customize the resolution of the 'node' field within a connection's edge. This is useful for data sources like NoSQL databases where relationships are stored as IDs. It shows defining an account object, a connection with a custom node resolver, and a user object with a connection to accounts. ```elixir object :account do field :id, non_null(:id) field :name, :string end connection node_type :account do edge do field :node, :account do resolve fn %{node: id}, _args, _info -> Account.find(id) end end end end object :user do field :name, string connection field :accounts, node_type: :account do resolve fn %{accounts: accounts}, _args, _info -> Absinthe.Relay.Connection.from_list(ids, args) end end end ``` -------------------------------- ### Define Forward-Only Paginated Connection Source: https://context7_llms Shows how to restrict a connection field to only support forward pagination using the `:paginate` argument set to `:forward`. This simplifies the pagination logic when backward traversal is not needed. ```elixir connection field :pets, node_type: :pet, paginate: :forward do ``` -------------------------------- ### Absinthe.Relay.Connection.Notation.connection/2 - Define a Pet Connection Source: https://context7_llms Shows how to define a basic Relay connection type for a given node type, `:pet`. This macro generates the necessary `:pet_connection` and `:pet_edge` types. It also illustrates how to provide a custom name for the connection and edge types. ```elixir connection node_type: :pet connection :favorite_pets, node_type: :pet ``` -------------------------------- ### Absinthe.Relay.Connection.limit/1 and Absinthe.Relay.Connection.limit/2 Source: https://context7_llms Functions to determine the number of records for pagination, with limit/2 allowing a user-defined upper bound. ```APIDOC ## Query Parameters - Pagination Limit ### Description These parameters control the maximum number of records to retrieve in a paginated request. ### Parameters #### Query Parameters - **first** (Int) - Optional - The desired number of records to fetch (forward pagination). - **last** (Int) - Optional - The desired number of records to fetch (backward pagination). - **max** (Int) - Optional - A user-defined upper bound for the number of records that can be retrieved, regardless of the `first` or `last` parameters. ``` -------------------------------- ### Define a Classic Relay Mutation with Input and Output Source: https://context7_llms Defines a simple mutation field ':simple_mutation' using Absinthe.Relay.Mutation.Notation.Classic. It accepts an 'input' argument with 'input_data' and returns a 'result' field. The resolver function only processes 'input_data', and 'clientMutationId' is handled automatically. ```elixir mutation do payload field :simple_mutation do input do field :input_data, non_null(:integer) end output do field :result, :integer end resolve fn %{input_data: input_data}, _ -> # Some mutation side-effect here {:ok, %{result: input_data * 2}} end end end ``` -------------------------------- ### Absinthe.Relay.Connection.page_info/0 (type) Source: https://context7_llms Defines the type for page information, indicating pagination status like next/previous page availability and start/end cursors. ```APIDOC ### Types #### pageInfo Contains information about the current state of pagination, including whether there are more pages available and the cursors for the start and end of the current page. ``` -------------------------------- ### Configure Global ID Translator - Absinthe.Relay.Schema Source: https://context7_llms Demonstrates how to configure a custom global ID translator for an Absinthe schema. This can be done inline within the schema definition using `use Absinthe.Relay.Schema` or via Mix configuration. The translator handles encoding and decoding of global IDs. ```elixir defmodule MyApp.Schema do use Absinthe.Schema use Absinthe.Relay.Schema, [ flavor: :modern, global_id_translator: MyApp.Absinthe.IDTranslator ] # ... end config Absinthe.Relay, MyApp.Schema, global_id_translator: MyApp.Absinthe.IDTranslator ``` -------------------------------- ### Absinthe.Relay.Connection.offset_to_cursor/1 Source: https://context7_llms Generates a Relay-compliant cursor string from a given offset value. ```APIDOC ## Cursor Generation ### Description This process involves converting an internal offset value into an opaque string format (cursor) that can be used for pagination. ### Parameters #### Path Parameters - **offset** (Int) - Required - The numerical offset from the beginning of the dataset. ``` -------------------------------- ### Absinthe.Relay.Connection.offset/1 Source: https://context7_llms Calculates the offset for pagination, considering the limit for backwards pagination and returning nil if no offset is specified. ```APIDOC ## Query Parameters - Pagination Offset ### Description This parameter specifies the starting point for retrieving a subset of records in a paginated request. ### Parameters #### Query Parameters - **after** (String) - Optional - A cursor string representing the position after which to start fetching records. - **before** (String) - Optional - A cursor string representing the position before which to start fetching records. Used in conjunction with `last` for backwards pagination. ``` -------------------------------- ### Absinthe.Relay.Connection.Notation.connection/2 (macro) Source: https://context7_llms Defines a Relay connection type for a given node type, automatically generating connection and edge types. ```APIDOC ## Define Connection Type ### Description This macro is used to define a Relay-compliant connection type for a specific node type. It automatically generates the corresponding connection and edge types. ### Method Macro ### Endpoint N/A (Schema definition) ### Parameters #### Path Parameters - **connection_name** (atom) - Optional - The custom name for the connection type (defaults to `node_type` + "Connection"). - **node_type** (atom) - Required - The type of the node the connection will be for. #### Query Parameters None #### Request Body None ### Request Example ```elixir connection node_type: :pet connection :favorite_pets, node_type: :pet do field :total_age, :float do resolve fn _, %{source: conn} -> sum = conn.edges |> Enum.map(fn edge -> edge.node.age) |> Enum.sum {:ok, sum} end end edge do # Customizations for the edge type end end ``` ### Response #### Success Response (200) N/A (Schema definition) #### Response Example N/A ``` -------------------------------- ### Absinthe.Relay.Connection.Notation.edge/2 (macro) Source: https://context7_llms Allows customization of the edge type within a connection definition. ```APIDOC ## Customize Edge Type ### Description This macro is used within a `connection` definition block to customize the generated edge type, allowing for additional fields or custom resolvers. ### Method Macro ### Endpoint N/A (Schema definition) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```elixir connection node_type: :pet do edge do field :node_name_backwards, :string do resolve fn _, %{source: edge} -> {:ok, edge.node.name |> String.reverse} end end end end ``` ### Response #### Success Response (200) N/A (Schema definition) #### Response Example N/A ``` -------------------------------- ### Absinthe.Relay.Node.Helpers.parsing_node_ids/2 Source: https://context7_llms Wraps a resolver to parse node (global) ID arguments before execution. Deprecated, use `Absinthe.Relay.Node.ParseIDs` middleware instead. ```APIDOC ## Absinthe.Relay.Node.Helpers.parsing_node_ids/2 ### Description Wrap a resolver to parse node (global) ID arguments before it is executed. Note: This function is deprecated and will be removed in a future release. Use the `Absinthe.Relay.Node.ParseIDs` middleware instead. For each argument: - If a single node type is provided, the node ID in the argument map will be replaced by the ID specific to your application. - If multiple node types are provided (as a list), the node ID in the argument map will be replaced by a map with the node ID specific to your application as `:id` and the parsed node type as `:type`. ### Method `parsing_node_ids/2` ### Endpoint N/A (Function within a module) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```elixir # Parse a node (global) ID argument :item_id as an :item type. resolve parsing_node_ids(&my_field_resolver/2, item_id: :item) # Parse a node (global) ID argument :interface_id into one of multiple node types. resolve parsing_node_ids(&my_field_resolver/2, interface_id: [:item, :thing]) ``` ### Response #### Success Response (200) Depends on the underlying resolver function. #### Response Example See the Request Example for how arguments are modified before passing to the resolver. ``` -------------------------------- ### Customize Connection and Edge Types Source: https://context7_llms Illustrates customizing generated Relay connection and edge types by adding extra fields. This allows for enriching the connection data with additional information relevant to the application. ```elixir connection node_type: :pet do field :twice_edges_count, :integer do resolve fn _, %{source: conn} -> {:ok, length(conn.edges) * 2} end end edge do field :node_name_backwards, :string do resolve fn _, %{source: edge} -> {:ok, edge.node.name |> String.reverse} end end end end ``` -------------------------------- ### Absinthe.Relay.Connection.cursor/0 (type) Source: https://context7_llms Defines the type for an opaque pagination cursor, typically base64 encoded. ```APIDOC ### Types #### cursor An opaque pagination cursor. Internally represented as `arrayconnection::$offset` and typically base64 encoded. ``` -------------------------------- ### Define Relay Mutation Input Type using Absinthe Source: https://context7_llms Defines the input type for a GraphQL mutation payload using Absinthe's `input` macro. This is a convenience macro for defining the structure of data expected by a mutation. It takes the mutation name and a block defining the fields. ```elixir defmodule MyAppWeb.Resolvers.MyMutations do alias Absinthe.Relay.Mutation.Notation.Modern defmodule CreateUserInput do use Modern.input, name: :create_user field :name, :string field :email, :string end # ... mutation definition using CreateUserInput end ``` -------------------------------- ### Response for Classic Relay Mutation Query Source: https://context7_llms The expected JSON response from a GraphQL query to the ':simple_mutation' field defined with Absinthe.Relay.Mutation.Notation.Classic. It shows the resolved 'result' and the echoed 'clientMutationId'. ```json { "data": { "simpleMutation": { "result": 4, "clientMutationId": "abc" } } } ``` -------------------------------- ### Define Relay Mutation Output Type using Absinthe Source: https://context7_llms Defines the output (payload) type for a GraphQL mutation using Absinthe's `output` macro. This macro specifies the shape of the data returned by a mutation. It takes the mutation name and a block defining the fields. ```elixir defmodule MyAppWeb.Resolvers.MyMutations do alias Absinthe.Relay.Mutation.Notation.Modern defmodule CreateUserPayload do use Modern.output, name: :create_user field :user, :user field :client_mutation_id, :string end # ... mutation definition returning CreateUserPayload end ``` -------------------------------- ### Configure Schema-Wide Node ID Parsing with Absinthe.Relay.Node.ParseIDs Source: https://context7_llms Configures `Absinthe.Relay.Node.ParseIDs` middleware globally for all top-level query fields. This approach centralizes the ID parsing rules within the schema definition, reducing repetition in individual field configurations. The `@node_id_rules` attribute defines the mapping for various ID arguments. ```elixir defmodule MyApp.Schema do # Schema ... @node_id_rules [ item_id: :item, interface_id: [:item, :thing], ] def middleware(middleware, _, %Absinthe.Type.Object{identifier: :query}) do [{Absinthe.Relay.Node.ParseIDs, @node_id_rules} | middleware] end def middleware(middleware, _, _) do middleware end end ``` -------------------------------- ### Absinthe.Relay.Node.from_global_id/2 Source: https://context7_llms Parses a global ID into its type and ID components, given a schema. Handles valid, invalid, and unknown types. ```APIDOC ## Absinthe.Relay.Node.from_global_id/2 ### Description Parse a global ID, given a schema. To change the underlying method of decoding a global ID, see `Absinthe.Relay.Node.IDTranslator`. ### Method `from_global_id/2` ### Endpoint N/A (Function within a module) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```elixir from_global_id(nil, Schema) from_global_id("UGVyc29uOjE=", Schema) from_global_id("GHNF", Schema) from_global_id("Tm9wZToxMjM=", Schema) from_global_id("Tm9wZToxMjM=", Schema) # Assuming 'Item' is not a valid node type ``` ### Response #### Success Response (200) - `{:ok, nil}` - If the input global ID is nil. - `{:ok, %{type: atom(), id: binary()}}` - If the global ID is successfully parsed and the type is valid. #### Error Response - `{:error, binary()}` - If the global ID is invalid, the type is unknown, or the type is not a valid node. #### Response Example ```elixir {:ok, nil} {:ok, %{type: :person, id: "1"}} {:error, "Could not decode ID value `GHNF'"} {:error, "Unknown type `Nope'"} {:error, "Type `Item' is not a valid node type"} ``` ``` -------------------------------- ### Configure Global Node ID Type in Absinthe Application Source: https://context7_llms Globally configures the type for the `id` field used in Relay Node objects within an Absinthe application. This setting is applied via the application's configuration file. ```elixir config :Absinthe.Relay, node_id_type: :uuid ``` -------------------------------- ### Parse Nested Node IDs with Absinthe.Relay.Node.ParseIDs Source: https://context7_llms Handles the parsing of nested node (global) ID arguments within input objects. This middleware recursively processes keyword lists to transform IDs at various levels of a nested structure, simplifying complex input handling for mutations. ```elixir input_object :parent_input do field :id, non_null(:id) field :children, list_of(:child_input) field :child, non_null(:child_input) end input_object :child_input do field :id, non_null(:id) end mutation do payload field :update_parent do input do field :parent, :parent_input end output do field :parent, :parent end middleware Absinthe.Relay.Node.ParseIDs, parent: [ id: :parent, children: [id: :child], child: [id: :child] ] resolve &resolve_parent/2 end end ``` -------------------------------- ### Define Node Interface for Global Object Identification in Absinthe Source: https://context7_llms Defines a Relay-compliant Node interface for an Absinthe schema. This interface allows querying objects by a global ID. The `resolve_type` function determines the concrete object type based on the resolved data. ```elixir defmodule MyAppWeb.Schema do use Absinthe.Schema alias Absinthe.Relay.Node node interface do resolve_type fn %{age: _}, _ -> :person %{employee_count: _}, _ -> :business _, _ -> nil end end # ... other schema definitions end ``` -------------------------------- ### Absinthe.Relay.Connection.edge/0 (type) Source: https://context7_llms Defines the structure for a Relay connection edge, which includes a node and its cursor. ```APIDOC ### Types #### edge Represents an edge in a Relay connection. An edge typically contains a `node` (the actual data item) and a `cursor`. ``` -------------------------------- ### Response for Modern Relay Mutation Query Source: https://context7_llms The expected JSON response from a GraphQL query to a mutation defined with Absinthe.Relay.Mutation.Notation.Modern. It shows the resolved 'result' field. ```json { "data": { "simpleMutation": { "result": 4 } } } ``` -------------------------------- ### Define Node ID Parsing Rules - Absinthe.Relay.Node.ParseIDs Source: https://context7_llms This snippet demonstrates how to define rules for parsing node IDs in Absinthe. Relay. Node. ParseIDs. It shows how to specify a single valid node type or multiple valid node types for a given ID. The behavior when an ID is null is also noted. ```elixir [ item_id: :item ] ``` ```elixir [ item_id: [:foo, :bar] ] ``` -------------------------------- ### Parse Node IDs in Resolvers - Absinthe.Relay.Node.Helpers.parsing_node_ids/2 Source: https://context7_llms A deprecated helper to wrap resolvers for parsing node (global) ID arguments. It can parse a single node type, replacing the argument with the application-specific ID, or multiple types, returning a map with type and ID. Use `Absinthe.Relay.Node.ParseIDs` middleware instead. ```elixir resolve parsing_node_ids(&my_field_resolver/2, item_id: :item) resolve parsing_node_ids(&my_field_resolver/2, interface_id: [:item, :thing]) ``` -------------------------------- ### Absinthe.Relay.Node.to_global_id/3 Source: https://context7_llms Generates a global ID from a node type name and an internal ID, using a provided schema. ```APIDOC ## Absinthe.Relay.Node.to_global_id/3 ### Description Generate a global ID given a node type name and an internal (non-global) ID given a schema. To change the underlying method of encoding a global ID, see `Absinthe.Relay.Node.IDTranslator`. ### Method `to_global_id/3` ### Endpoint N/A (Function within a module) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```elixir to_global_id("Person", "123") to_global_id(:person, "123", SchemaWithPersonType) to_global_id(:person, nil, SchemaWithPersonType) ``` ### Response #### Success Response (200) - `binary()` - The generated global ID. - `nil` - If the internal ID is nil. #### Response Example ```elixir "UGVyc29uOjEyMw==" nil ``` ``` -------------------------------- ### Absinthe.Relay.Node.IDTranslator.from_global_id/2 Callback Source: https://context7_llms Callback function to convert a globally unique ID to a node's type name and ID. Returns an error tuple on failure. ```APIDOC ## Absinthe.Relay.Node.IDTranslator.from_global_id/2 Callback ### Description Converts a globally unique ID to a node's type name and ID. Returns `{:ok, type_name, source_id}` on success. Returns `{:error, binary}` on failure. ### Method `from_global_id/2` (Callback) ### Endpoint N/A (Callback within an ID Translator module) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```elixir # Assuming MyApp.Absinthe.IDTranslator is implemented and configured MyApp.Absinthe.IDTranslator.from_global_id("UGVyc29uOjEyMw==", Schema) ``` ### Response #### Success Response (200) - `{:ok, type_name, source_id}` - Where `type_name` is the node type and `source_id` is the internal ID. #### Error Response - `{:error, binary()}` - A message indicating the failure reason. #### Response Example ```elixir {:ok, "Person", "123"} {:error, "Could not decode ID value `InvalidID'"} ``` ``` -------------------------------- ### Define Relay Node Object Type with Absinthe Source: https://context7_llms Defines a GraphQL object type that implements the Relay Node interface using Absinthe's `node object` macro. This automatically adds a global `id` field and handles ID translation. Custom ID types and fetchers can be specified. ```elixir defmodule MyAppWeb.Schema do use Absinthe.Schema alias Absinthe.Relay.Node node object :person do field :name, :string field :age, :string end node object :business, id_type: :uuid do field :name, :string field :industry, :string end # Example with custom ID fetcher # node object :thing, id_fetcher: &my_custom_id_fetcher/2 do # field :name, :string # end end ``` -------------------------------- ### Absinthe.Relay.Node.IDTranslator Behaviour Source: https://context7_llms Defines the behaviour for ID translators, which handle encoding and decoding of global IDs used in Relay nodes. Provides configuration options. ```APIDOC ## Absinthe.Relay.Node.IDTranslator Behaviour ### Description An ID translator handles encoding and decoding a global ID used in a Relay node. This module provides the behaviour for implementing an ID Translator. An example use case of this module would be a translator that encrypts the global ID. To use an ID Translator in your schema there are two methods: #### Inline Config ```elixir defmodule MyApp.Schema do use Absinthe.Schema use Absinthe.Relay.Schema, [ flavor: :modern, global_id_translator: MyApp.Absinthe.IDTranslator ] # ... end ``` #### Mix Config ```elixir config Absinthe.Relay, MyApp.Schema, global_id_translator: MyApp.Absinthe.IDTranslator ``` ### Method Behaviour definition ### Endpoint N/A (Configuration/Behaviour) ### Parameters None ### Request Example See configuration examples above. ### Response N/A ### Response Example N/A ``` -------------------------------- ### Convert Global ID - Absinthe.Relay.Node.from_global_id/2 Source: https://context7_llms Parses a global Relay ID into its constituent type and ID. It requires a schema to validate the type. Handles valid IDs, invalid base64 values, unknown types, and types that are not valid nodes. Returns an {:ok, %{type: ..., id: ...}} tuple on success or an {:error, reason} tuple on failure. ```elixir iex> from_global_id(nil, Schema) {:ok, nil} iex> from_global_id("UGVyc29uOjE=", Schema) {:ok, %{type: :person, id: "1"}} iex> from_global_id("GHNF", Schema) {:error, "Could not decode ID value `GHNF'"} iex> from_global_id("Tm9wZToxMjM=", Schema) {:error, "Unknown type `Nope'"} iex> from_global_id("Tm9wZToxMjM=", Schema) {:error, "Type `Item' is not a valid node type"} ``` -------------------------------- ### Parse Multiple Node ID Arguments with Absinthe.Relay.Node.ParseIDs Source: https://context7_llms Parses a node (global) ID argument that can resolve to one of multiple node types, like `:interface_id`. It replaces the ID with a map containing the application-specific ID and the parsed node type. This provides flexibility for fields that can return different kinds of nodes. ```elixir field :foo, :foo do arg :interface_id, non_null(:id) middleware Absinthe.Relay.Node.ParseIDs, interface_id: [:item, :thing] resolve &foo_resolver/3 end ``` -------------------------------- ### Define Node Field for Global ID Queries in Absinthe Source: https://context7_llms Defines the root `node` field in an Absinthe schema, enabling global ID queries. The `resolve` function handles the logic of fetching an object based on its parsed global ID (type and internal ID). ```elixir defmodule MyAppWeb.Schema do use Absinthe.Schema alias Absinthe.Relay.Node query do # ... other query fields node field do resolve fn %{type: :person, id: id}, _ -> {:ok, Map.get(@people, id)} %{type: :business, id: id}, _ -> {:ok, Map.get(@businesses, id)} end end end # ... other schema definitions end ``` -------------------------------- ### Fetch Default ID - Absinthe.Relay.Node.default_id_fetcher/2 Source: https://context7_llms Retrieves the raw, non-global ID from a value map. It specifically looks for an `:id` key. If present, it attempts to convert the value to a string; otherwise, it returns nil. This function is used internally by Absinthe for ID resolution. ```elixir iex> default_id_fetcher(%{id: "foo"}) "foo" iex> default_id_fetcher(%{id: 123}) "123" iex> default_id_fetcher(%{id: nil}) nil iex> default_id_fetcher(%{nope: "no_id"}) nil ``` -------------------------------- ### Absinthe.Relay.Node.default_id_fetcher/2 Source: https://context7_llms Fetches the default ID from a given value, coercing it to a binary string. Returns nil if the ID is not found or is nil. ```APIDOC ## Absinthe.Relay.Node.default_id_fetcher/2 ### Description The default ID fetcher used to retrieve raw, non-global IDs from values. * Matches `:id` out of the value. * If it's `nil`, it returns `nil` * If it's not nil, it coerces it to a binary using `Kernel.to_string/1` ### Method `default_id_fetcher/2` ### Endpoint N/A (Function within a module) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```elixir %{{:id => "foo"}} %{{:id => 123}} %{{:id => nil}} %{{:nope => "no_id"}} ``` ### Response #### Success Response (200) - `binary()` - The extracted and coerced ID, or `nil`. #### Response Example ```elixir "foo" "123" nil nil ``` ``` -------------------------------- ### Convert Local ID to Global ID with Absinthe.Relay.Node.IDTranslator.to_global_id/3 Source: https://context7_llms Converts a node's type name and local ID into a globally unique identifier. It returns `{:ok, global_id}` upon successful conversion and `{:error, binary}` if an error occurs during the process. This function is crucial for maintaining consistent and unique identifiers across a Relay-compliant GraphQL API. ```elixir Absinthe.Relay.Node.IDTranslator.to_global_id(:user, user.id) # => {:ok, "dXNlcjoz"} ``` -------------------------------- ### Generate Global ID - Absinthe.Relay.Node.to_global_id/3 Source: https://context7_llms Generates a global Relay ID from a node type name and its internal ID, using a provided schema. It supports type names as atoms or strings. Returns nil if the internal ID is nil. This is the inverse operation of `from_global_id`. ```elixir iex> to_global_id("Person", "123") "UGVyc29uOjEyMw==" iex> to_global_id(:person, "123", SchemaWithPersonType) "UGVyc29uOjEyMw==" iex> to_global_id(:person, nil, SchemaWithPersonType) nil ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.