Skip to content

feat: add backwards compatible polymorphic resource support #359

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

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

nduitz
Copy link

@nduitz nduitz commented Mar 13, 2025

Hey there,
I tried my best to add support for polymorphic resources.
The idea is to allow the user to infer resource specifics from the given data.
Currently this only allows type and fields to be polymorphic. I will probably implement relationships as well.

Additionally I only tested it to work as a relation with an api endpoint of its own - quite frankly there are some things that are not possible:
The QueryParser fetches view.fields() at a moment where no data is present, thus inference is not possible.

This is my first time really working with a behaviour, my approach on implementing a backwards compatible solution felt a bit clunky, so any feedback is very welcome. :)

@nduitz nduitz requested a review from a team as a code owner March 13, 2025 10:48
@mattpolzin
Copy link
Member

Thanks for the PR. I’m on a trip for the next two weeks so unless someone else jumps in there will be a bit of a delay in looking this over. Just wanted to let you know I see the PR!

@mattpolzin mattpolzin self-requested a review March 14, 2025 22:01
@doomspork doomspork changed the title add backwards compatible polymorphic resource support feat: add backwards compatible polymorphic resource support Mar 15, 2025
Copy link
Member

@mattpolzin mattpolzin left a comment

Choose a reason for hiding this comment

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

This looks like a pretty reasonable approach to me. I'll do a bit more thinking on it but in the meantime there are a few things I found to comment on.

@@ -140,10 +140,12 @@ defmodule JSONAPI.View do
@type options :: keyword()
@type resource_id :: String.t()
@type resource_type :: String.t()
@type polymorphic_resource :: boolean()
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't get used best I can tell. I'd also argue that aliasing the boolean type to polymorphic_resource doesn't add clarity if used in a type spec (the statement "this is a value of type polymorphic_resource" almost sounds like it is describing a polymorphic resource instead of a boolean indicating whether a resource is polymorphic).

def fields, do: raise("Need to implement fields/0")

@impl View
def polymorphic_fields(_data), do: nil
Copy link
Member

Choose a reason for hiding this comment

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

The type of this callback does not include nil (same for the other new callback).

Copy link
Member

Choose a reason for hiding this comment

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

If in practice this function just gets ignored whenever @polymorphic_resource is false, may as well return [] (which fits its type spec) instead of nil.

Copy link
Member

Choose a reason for hiding this comment

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

An alternative design might be explicitly allow nil and avoid the need for the @polymorphic_type boolean by instead defining the resource_type/1 function to be polymorphic_type(data) if it isn't nil and otherwise type(). Having the @polymorphic_type boolean is probably the better option, though.

@nduitz nduitz force-pushed the polymorphic_resources branch from ee95988 to fa2d880 Compare April 10, 2025 09:45
@nduitz
Copy link
Author

nduitz commented May 6, 2025

Hey there,
thanks for your feedback and sorry for the long period of silence.
I had a lot of work to do and made some additions to this I am currently using with no problems at all.
I will try to implement your suggestions soon :)

@nduitz
Copy link
Author

nduitz commented Jun 5, 2025

Hey there :)
I did some refactoring of my first approach.
WDYT?
Additionally I updated the docs to get a better understanding of what is possible and how to use the functionality.

@mattpolzin mattpolzin self-requested a review June 13, 2025 17:43
@mattpolzin
Copy link
Member

Hey! Sorry, I kept not thinking of this PR when I had time to look at it because it had been removed from my review queue after my previous comments. I've added it back into my queue so I should get this reviewed in the next few (week) days.

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.

2 participants