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

Deserializer plug #222

Merged
merged 25 commits into from
Mar 18, 2020
Merged

Conversation

snewcomer
Copy link
Contributor

@snewcomer snewcomer commented Feb 25, 2020

close #210

Copy link
Member

@doomspork doomspork left a comment

Choose a reason for hiding this comment

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

Thanks for doing this @snewcomer! Couple of questions

lib/jsonapi/utils/param_parser.ex Outdated Show resolved Hide resolved
test/jsonapi/plugs/deserializer_test.exs Outdated Show resolved Hide resolved
Copy link
Member

@doomspork doomspork left a comment

Choose a reason for hiding this comment

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

Looks good to me @snewcomer! Do we want to give @jeregrine or @jherdman a chance to look this over before we merge and release?

Copy link
Contributor

@jherdman jherdman left a comment

Choose a reason for hiding this comment

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

Apologies, my head is a little out of the game on this project these days, so I may not be the best person to ask. That said, how does this differ from the UnderscoreParameters plug? This is a bit unclear from the docs included with the new code.

@snewcomer
Copy link
Contributor Author

Welp you are right. My too quick of a take before I started this PR was it was for query params but I didn't take it to it's logical conclusion.

I'll close this and see if I can help with some docs if need be!

@snewcomer
Copy link
Contributor Author

Reopening to explore the reverse of serializing...

@snewcomer snewcomer added enhancement and removed wip labels Mar 1, 2020
@snewcomer snewcomer requested a review from doomspork March 2, 2020 05:40
@snewcomer snewcomer requested a review from jherdman March 14, 2020 17:40
"id" => "1",
"type" => "user"
"foo-bar" => true,
"baz-id" => "2"
Copy link
Contributor

Choose a reason for hiding this comment

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

What happens with polymorphic records? A totally contrived example...

"relationships" => %{
  "authors" => %{
    "data" => [
      %{"type" => "staff", "id" => "123"},
      %{"type" => "contributor", "id" => "456"}
    ]
  }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great idea! Added a test. I'm not sure though there is a way to process other than this...

738c2b9#diff-ced812e7235b283a4598ca0ae957ecd0R91

Otherwise, down in this file, I have tests for includes with many types.

README.md Outdated
Comment on lines 131 to 133
3. Deserializing *incoming* body params requires you add the
`JSONAPI.Deserializer` Plug to your API's pipeline. Note that the deserializer
expects the same casing for your *outgoing* params as your *incoming* params.
Copy link
Contributor

Choose a reason for hiding this comment

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

I find this description a tad confusing. The way I understand this plug it sort of "flattens" the parts of a resource object to make it more convenient to use, especially when creating or updating records. The description, as is, has some overlap with the language used by the UnderscoreParmeters section, and has overlap with the sample code used by the UnderscoreParamters pipeline.

How about this:

JSONAPI.Deserializer is a plug designed to make a JSON:API resource object more convenient to work with when creating or updating resources. This plug works by taking the resource object format and flattening it into an easier to manipulate Map.

Your pipeline in a Phoenix app might look something like this:

pipeline :api do
  plug JSONAPI.EnsureSpec # not required, but recommended for Deserializer
  plug JSONAPI.Deserializer
end

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes reading again and you are right! Great suggestion!

@@ -0,0 +1,66 @@
defmodule JSONAPI.Deserializer do
@moduledoc """
This plug "deserializes" params for ease of use when casting to changesets.
Copy link
Contributor

Choose a reason for hiding this comment

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

Assuming my above stated understanding is correct, it may be prudent to use the word "flatten" instead of "deserialize".

lib/jsonapi/utils/data_to_params.ex Outdated Show resolved Hide resolved
end
end

@ct "application/vnd.api+json"
Copy link
Contributor

Choose a reason for hiding this comment

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

You may just want to reference, or alias, JSONAPI.mime_type so that we don't spread this string throughout the code.

assert result.params["bazId"] == "2"
end
end
end
Copy link
Contributor

Choose a reason for hiding this comment

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

This is really good, but you may want to add a has-many relationship example too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have a bunch of examples in data_to_params_test.exs. Do you think that is sufficient?

Copy link
Contributor

@jherdman jherdman left a comment

Choose a reason for hiding this comment

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

One last question above

"id" => "1",
"type" => "user",
"foo-bar" => true,
"baz-id" => ["2", "3"]
Copy link
Contributor

Choose a reason for hiding this comment

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

Doesn't this mean you have a bug? Imagine a system like this... I have a super class called "Car", and I want to create two records, a "Ford" and a "Subaru". The way I'm reading this you've lost the typing information that the user provided — thus in my scenario I wouldn't know that a user was creating a "Subaru" and a "Ford".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed! Great point.

2481ee9

e4ffe06

@snewcomer snewcomer requested a review from jherdman March 18, 2020 03:49
@jherdman jherdman merged commit 5e14139 into beam-community:master Mar 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Deserializer
3 participants