Skip to content

Support Elixir 1.18 JSON module as json_codec#310

Open
donleandro wants to merge 1 commit intoabsinthe-graphql:mainfrom
donleandro:feat/elixir-json-codec-support
Open

Support Elixir 1.18 JSON module as json_codec#310
donleandro wants to merge 1 commit intoabsinthe-graphql:mainfrom
donleandro:feat/elixir-json-codec-support

Conversation

@donleandro
Copy link
Copy Markdown
Contributor

Summary

Fixes #299.

When configuring json_codec: JSON to use Elixir 1.18's built-in JSON module, calls to JSON.encode!/2 fail because the built-in module expects an encoder function as the second argument, while this library passes a keyword list of options (the convention used by Jason).

This came up while upgrading to Elixir 1.18 on a project I work on (Shiko, a veterinary platform). The fix is minimal and fully backward compatible:

  • safe_encode!/3 in Absinthe.Plug: when opts is [] (which is the default when json_codec is configured as a bare module), it calls encode!/1 instead of encode!/2. Both Jason and JSON support arity-1. When opts is non-empty, it passes them through as before, so {Jason, [pretty: true]} etc. still works.
  • pretty_encode!/2 in Absinthe.Plug.GraphiQL: the GraphiQL interface calls encode!(value, pretty: true) for display purposes. Since the built-in JSON module does not support this keyword option, the helper checks whether the codec supports keyword-style opts and falls back to plain encoding when it does not.

No changes to the public API. Jason and Poison keep working exactly as before.

Changes

  • lib/absinthe/plug.ex - encode/4 and encode_json!/2 now go through safe_encode!/3
  • lib/absinthe/plug/graphiql.ex - all encode!(value, pretty: true) calls go through pretty_encode!/2
  • Tests added for safe_encode!/3 with both Jason and JSON, plus integration tests using json_codec: JSON for full request/response cycles (guarded with Code.ensure_loaded?(JSON) so they only run on Elixir >= 1.18)

Test plan

  • All 91 tests pass (86 existing + 5 new)
  • Verified with json_codec: JSON on Elixir 1.18.4
  • Verified Jason still works identically (default behavior)
  • New tests are skipped gracefully on Elixir < 1.18

When users set `json_codec: JSON`, calls to `JSON.encode!/2` fail
because the built-in JSON module expects an encoder function as its
second argument, not a keyword list of options like Jason does.

This introduces `safe_encode!/3` which calls `encode!/1` when opts is
empty (compatible with both Jason and JSON) and only passes opts when
non-empty (for codecs like Jason that support keyword options).

For GraphiQL's pretty-printing (`encode!(value, pretty: true)`), a
`pretty_encode!/2` helper detects whether the codec supports keyword
options and falls back to plain encoding for codecs like JSON.

Closes absinthe-graphql#299
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.

Support Elixir 1.18 JSON module

1 participant