Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement overridable global ID translator #93

Merged
merged 15 commits into from
Apr 12, 2018
Prev Previous commit
Next Next commit
Document behaviour
avitex committed Nov 9, 2017
commit 0cf86f276ab99abaaf809c4deb7023637691a3d6
17 changes: 13 additions & 4 deletions lib/absinthe/relay/node.ex
Original file line number Diff line number Diff line change
@@ -83,9 +83,9 @@ defmodule Absinthe.Relay.Node do

This will create an object type, `:person`, as you might expect. An `:id`
field is created for you automatically, and this field generates a global ID;
a Base64 string that's built using the object type name and the raw, internal
identifier. All of this is handled for you automatically by prefixing your
object type definition with `"node "`.
an opaque string that's built using a global ID translator (by default a
Base64 implementation). All of this is handled for you automatically by
prefixing your object type definition with `"node "`.

The raw, internal value is retrieved using `default_id_fetcher/2` which just
pattern matches an `:id` field from the resolved object. If you need to
@@ -101,6 +101,9 @@ defmodule Absinthe.Relay.Node do
end
```

For instructions on how to change the underlying method of decoding/encoding
a global ID, see `Absinthe.Relay.Node.IDTranslator`.

## Macros

For more details on node-related macros, see
@@ -128,6 +131,9 @@ defmodule Absinthe.Relay.Node do
@doc """
Parse a global ID, given a schema.

To change the underlying method of decoding a global ID,
see `Absinthe.Relay.Node.IDTranslator`.

## Examples

For `nil`, pass-through:
@@ -202,7 +208,10 @@ defmodule Absinthe.Relay.Node do
end

@doc """
Generate a global ID given a node type name and an internal (non-global) ID
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`.

## Examples

36 changes: 34 additions & 2 deletions lib/absinthe/relay/node/id_translator.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,39 @@
defmodule Absinthe.Relay.Node.IDTranslator do
@moduledoc """
An ID translator handles encoding and decoding a global ID
used in a relay node.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capitalize "Relay"


This module provides the behaviour for implementing an ID Translator.
Example use cases of this module would be a translator that encypts the
global ID or perhaps use a different base encoding.

## Example

A basic example that encodes the global ID by joining the `type_name` and
`source_id` with `":"`.

```
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
```
"""

@callback to_global_id(type_name :: binary, source_id :: binary | integer, schema :: atom) :: {:ok, binary} | {:error, binary}
@callback to_global_id(type_name :: binary, source_id :: binary | integer, schema :: atom) :: {:ok, binary} | {:error, binary}

@callback from_global_id(global_id :: binary, schema :: atom) :: {:ok, binary, binary} | {:error, binary}
@callback from_global_id(global_id :: binary, schema :: atom) :: {:ok, binary, binary} | {:error, binary}

end
2 changes: 1 addition & 1 deletion lib/absinthe/relay/node/id_translator/default.ex
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ defmodule Absinthe.Relay.Node.IDTranslator.Default do
[type_name, source_id] when byte_size(type_name) > 0 and byte_size(source_id) > 0 ->
{:ok, type_name, source_id}
_ ->
{:error, "Could not extract value from decoded ID `#{inspect decoded}'"}
{:error, "Could not extract value from decoded ID `#{inspect decoded}`"}
end
:error ->
{:error, "Could not decode ID value `#{global_id}'"}