-
Notifications
You must be signed in to change notification settings - Fork 3k
Use the built-in JSON library #6481
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
base: main
Are you sure you want to change the base?
Use the built-in JSON library #6481
Conversation
Now [`/hello/Frank`] in your browser should display `From messenger Frank` as plain text without any HTML. | ||
|
||
A step beyond this is rendering pure JSON with the [`json/2`] function. We need to pass it something that the [Jason library](`Jason`) can decode into JSON, such as a map. (Jason is one of Phoenix's dependencies.) | ||
A step beyond this is rendering pure JSON with the [`json/2`] function. We need to pass it something that the [JSON library](https://hexdocs.pm/elixir/JSON.html) can decode into JSON, such as a map. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
format: "\n$time $metadata[$level] $message\n" | ||
|
||
config :phoenix, | ||
json_library: Jason, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably here we would need to have something similar to if Code.ensure_loaded?(JSON), do: JSON, else: Jason
if that conditional loading trick makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it does and yes, we definitely need it (and also adjust the tests to assert the correct errors in CI)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah, for sure. I wasn't certain if the said approach (determining JSON availability by Code.ensure_loaded?
) is the correct one. But if it will do, then yes, I'll update the tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can wait for José to chime in. Sometimes you need Code.ensure_compiled
, but I think for a built in module ensure_loaded
should be fine?
lib/phoenix.ex
Outdated
""" | ||
def json_library do | ||
Application.get_env(:phoenix, :json_library, Jason) | ||
Application.get_env(:phoenix, :json_library, @default_json_library) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We cannot change the default here, as that would be a breaking change. We can only change it in new apps.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree. It makes things a bit simpler for this PR:
- Mark the default library in
Phoenix.json_library
as a breaking change for Phoenix v2.0 - Use
JSON
for new apps - Make sure that tests pass with both
JSON
andJason
libraries
What I'm not sure is whether changes in config/config.exs
are safe?
I could be wrong, but it seems that they aren't propagated to library users. The users will only see variables from application.env
, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing config is safe!
end | ||
|
||
assert_raise json_error, | ||
~r/invalid byte 111 at position \(byte offset\) 0|unexpected byte at position 0: 0x6F \("o"\)/, fn -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Address #6461
The changes set the built-in JSON library as a default JSON library.
The idea is to check whether the built-in JSON library is present and use it if so:
Correct me if I'm wrong, but I think a naive check of whether the library is present during compilation time should work, as it's a built-in library.
What I'm not sure about is whether such a move results in a breaking change.
It could be a breaking change for projects that don't specify the
json_library
and use@derive Jason.Encoder
on structures passed toPhoenix.Controller.json/2
. That sounds pretty niche, especially given that the template project includes:Also, I'm specifically leaving the
jason
dependency in place for pre-27 OTP versions.Please let me know what you think and whether the changes make sense. In other words, maybe it would be better to stick with
Jason
until Phoenix requires OTP 28.Similar discussions / changes:
Use Jason instead of Poison for json encoding by chrismccord #2734phoenixframework/phoenix
Investigate using Jason instead of Poison #2693phoenixframework/phoenix
Use JSON instead of Jason by kubosuke #234felt/geo