Skip to content

find with nil attribute #329

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

Closed
danielwheeler1987 opened this issue Jan 18, 2019 · 8 comments
Closed

find with nil attribute #329

danielwheeler1987 opened this issue Jan 18, 2019 · 8 comments

Comments

@danielwheeler1987
Copy link

Hello, so I have a concern related to the find method. I noticed that if for some reason the specified id for model record is nil and passed into the api find method it will interpolate the nil on the end of the query string when performing the request. This means the index action instead of the show action is called and returns the entire collection of specified model records. Wouldn't it be ideal for the api client lib to handle this nil behavior and throw a client error (argument error)? I would really like some feedback on this. I would prefer not to have to...

  1. Fork the lib.
  2. Handle nil checks via the consuming application.
  3. Write some custom hacks to handle checks in client wrappers.

Thanks, and TGIF :)

@gaorlov
Copy link
Collaborator

gaorlov commented Mar 20, 2019

Can you tell me a little bit more about what you're seeing? Does it hit http://api.example.com/models/nil, http://api.example.com/models?id=nil, or http://api.example.com/models? Can you also tell me a bit more about the use case when you're looking for a record with a nil primary key and what the expected behavior is?

@stokarenko
Copy link
Contributor

@gaorlov
In short, it hits http://api.example.com/models.

But the problem can be a critical for specific scenarios:

1
That is a bit curios, but json_api_client returns the array from find method, always.
The history of this fact was discussed here - #75

So, when we searching for a single resource by primary key, we typically write the things like

product = Product.find(id).first

2
The next thing which we need to notice - json_api_client will just interpolate the incoming find param to the end of API URL, just like that

http://somehost/api/v1/products/{id}

3
What will happen if we pass the blank id (nil or empty string) to the find method then?.. Ya, json_api_client will try to call the INDEX API endpoint instead of SHOW

http://somehost/api/v1/products/

Lets sum 1 + 2 + 3 - in case if id is blank, we will silently receive the product variable equal to some existing resource, with all the consequences.

Even worse, product variable will equal to random resource, it will be not Idempotent.

Once again - at the moment we receive the random resource when searching by blank primary key O_o

That is absolutely not what we expect to reach. That can give us a tons of unexpected and unexplained effects all around the system.

To fix that we patched the builder this way:

class MyBuilder < JsonApiClient::Query::Builder
      def find(args={}, collection: false)
        raise ::JsonApiClient::Errors::NotFound if !collection && args.blank?

        super(args)
      end

      def to_a
        @to_a ||= find(collection: true)
      end
      alias all to_a
end

Please let me know is that looks good enough for PR :)

@senid231
Copy link
Member

In case of singleton api endpoint current behaviour is correct.
I think we can add optional configuration on resource class level for that

@stokarenko
Copy link
Contributor

@senid231 Roger, just thought the same
Going to prepare PR draft soon )

@stokarenko
Copy link
Contributor

@senid231 @gaorlov here we go - #344

@gaorlov
Copy link
Collaborator

gaorlov commented May 24, 2019

@stokarenko marvelous. I really appreciate you doing this work! I left one small comment, but it looks solid otherwise. Thanks!

@stokarenko
Copy link
Contributor

@gaorlov force pushed with additional test )

@gaorlov
Copy link
Collaborator

gaorlov commented May 24, 2019

1.11.0 is live. Thanks for the contribution, @stokarenko

@gaorlov gaorlov closed this as completed May 24, 2019
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

No branches or pull requests

4 participants