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
Merged

Implement overridable global ID translator #93

merged 15 commits into from
Apr 12, 2018

Conversation

avitex
Copy link
Contributor

@avitex avitex commented Nov 3, 2017

As per #85

TODO

  • Documentation
  • Tests

@avitex
Copy link
Contributor Author

avitex commented Nov 3, 2017

LMKWYT.
Will write some documentation and a couple of tests this weekend.

@@ -200,6 +200,9 @@ defmodule Absinthe.Relay.Node do
end
end

@doc """
Similar to `from_global_id/2` but raises `RuntimeError` if fails to decode global ID.
Copy link
Contributor Author

@avitex avitex Nov 21, 2017

Choose a reason for hiding this comment

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

@bruce Not sure if RuntimeError is correct in this context (same with to_global_id!/2). What do you think?

Copy link
Contributor

@bruce bruce left a comment

Choose a reason for hiding this comment

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

@avitex Really good work on this. There are a few changes here that I'd like you to look at, and if you have any questions please let me know.

We need to be really explicit about any backwards compatibility issues, so let's also make sure we chat about that before we merge this; we really should stay backwards-compatible until v1.5.

@@ -110,6 +113,8 @@ defmodule Absinthe.Relay.Node do

require Logger

@type global_id_t :: binary
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's make this @type global_id :: binary (we're moving away from the _t suffix in our types to better match wider community conventions).

{:ok, result} ->
result
{:error, err} ->
raise RuntimeError, message: err
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's make a dedicated, specific error type for this in case anyone wants to catch it.

@@ -0,0 +1,25 @@
defmodule Absinthe.Relay.Node.IDTranslator.Default do
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's be more explicit with this and call it Absinthe.Relay.Node.IDTranslator.Base64—the fact it's the default doesn't tell you what it does when you see it referenced in code/configuration.

@@ -5,10 +5,26 @@ defmodule Absinthe.Relay.Schema do
See `Absinthe.Relay`.
"""

defmacro __using__(opts) do
defmacro __using__ do
Copy link
Contributor

Choose a reason for hiding this comment

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

Not needed.

use Absinthe.Relay.Schema won't call this; use always calls __using__/1, even if no options are provided.

Reference: https://hexdocs.pm/elixir/Kernel.html#use/2

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Learn something new every day, never knew this.

import_types Absinthe.Relay.Connection.Types

def __absinthe_relay_global_id_translator__ do
Keyword.get(unquote(opts), :global_id_translator, nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

Third argument not necessary. Keyword.get/2 returns nil when not found.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, this is an old habit I have in being a bit too explicit

end
```
"""

Copy link
Contributor

Choose a reason for hiding this comment

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

Callback docs?

|> apply(direction, args ++ [schema])
end

@non_relay_schema_error "Non relay schema provided"
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"


@non_relay_schema_error "Non relay schema provided"

defp global_id_translator(:env, schema) do
Copy link
Contributor

Choose a reason for hiding this comment

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

It might be nice to have this just be global_id_translator/1, and have the env vs schema vs default be an implementation concern of the function vs using a "magic atom" argument. Could you also make it def instead of defp for testing/debugging purposes?

With this in place, translate_global_id/3 could be simplified quite a bit.

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"

apply(Absinthe.Relay.Node.IDTranslator.Default, direction, args ++ [nil])
end
defp translate_global_id(schema, direction, args) do
(global_id_translator(:env, schema) || global_id_translator(:schema, schema) || Absinthe.Relay.Node.IDTranslator.Default)
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm pretty sure that the environment setting should be the fallback for the explicit schema (use) setting, not the other way around.

@avitex
Copy link
Contributor Author

avitex commented Nov 22, 2017

In terms of backwards compatibility, I think a solution till v1.5 could be to make to_global_id/2 return nil on an error as it does now in v1.4.

This would mean to_global_id!/2 would then need to return nil early if source_id was nil and raise if to_global_id/2 returns nil (Following the behaviour of to_global_id(_node_type, nil, _schema)).

Thoughts?

@bruce bruce self-assigned this Nov 22, 2017
@bruce
Copy link
Contributor

bruce commented Dec 5, 2017

Note that to_global_id(_node_type, nil, _schema) doesn't raise, it warns and returns an error tuple.

In general, we want to avoid raising during runtime, as it doesn't give us a good method of returning useful information to the API user (exceptions are something we try to reserve for mistakes by the schema designer).

If you can make this more backwards compatible for now, let's do it.

@avitex
Copy link
Contributor Author

avitex commented Dec 5, 2017

Not sure if I understand completely.

Currently in the wild:

Perhaps you are talking about global_id_resolver/2 which warns via report_fetch_id_error/2 and returns a error tuple?

I understand the benefits on not raising on runtime, but to_global_id/2 currently does not return an error tuple, which was my reasoning behind providing to_global_id!/2 (a stepping stone for upgrading).

I can foresee to_global_id/2 returning error tuples on v1.5.

I'll make the changes I outlined in my previous comment and push them up for review.

@bruce
Copy link
Contributor

bruce commented Dec 5, 2017

Ah, yes, sorry. Apparently I misread. That's what I get for skimming through code on my phone.

Personally, I see very little benefit in using a ! version that raises, for the reasons I mentioned earlier. I think it's fine if we provide it, but our defaults should certainly more gracefully handle errors.

@avitex
Copy link
Contributor Author

avitex commented Dec 5, 2017

Yeah, I agree with you. I'll remove it for this PR but we could introduce it in v1.5 and remove in a later version. Only purpose it serves is for a quick upgrade to the next version.

@avitex
Copy link
Contributor Author

avitex commented Mar 8, 2018

Heya @bruce, I've removed the bang functions and fixed the conflicts. Let me know if there is anything else you'd like to discuss or change.

@tlvenn
Copy link
Member

tlvenn commented Mar 22, 2018

@bruce any chance to merge this soon ? Thanks in advance !

@madebyherzblut
Copy link

I would love to see this merged (and released) as well. We use hashids to obfusicate the ID and a global ID translator would remove a lot of code. Let me know if I can help in any way 😊

@bruce
Copy link
Contributor

bruce commented Apr 11, 2018

Sorry folks, we're finally going to do some passes on PRs (we've been crushed with other stuff/exhausted) and will look at getting this in very soon.

@bruce bruce merged commit ff4799a into absinthe-graphql:master Apr 12, 2018
@bruce
Copy link
Contributor

bruce commented Apr 12, 2018

This will ship in the next release (bundled with some other changes); will try to get it out today/tomorrow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants