grape icon indicating copy to clipboard operation
grape copied to clipboard

How to define multiple allowed types when one of them is array of hash?

Open huyvohcmc opened this issue 4 years ago • 5 comments

Currently I got an endpoint with params like this:

params do
  requires :content, types: [String, Hash]
end

When content can be array of hash also ([{"type": "paragraph", "children": [{"text": "test"}]}]), how are we gonna define it?

params do
  requires :content, types: [String, Hash, Array[Hash]]
end

with the code above, params[:content] will be

#<Hashie::Mash #<Hashie::Mash children=#<Hashie::Array [#<Hashie::Mash text="test">]>

which I don't think is correct? It looks like a hash of array. My expectation is params[:content] will be this:

[#<Hashie::Mash children=[#<Hashie::Mash text="test">] type="paragraph">]

because with that I can store params[:content] directly to a JSON column in the DB.

huyvohcmc avatar Jan 14 '21 10:01 huyvohcmc

This should work. Are you POSTing content-type=JSON? Turn this into a spec otherwise so we can see what's going on.

dblock avatar Jan 14 '21 14:01 dblock

Yes I'm posting with content-type = application/json

class Testing < Grape::API
  namespace :testing do
    params do
      requires :content, types: [String, Hash, Array]
    end
    post do
      declared(params)[:content]
    end
  end
end
curl --request POST \
  --url http://localhost:3000/api/testing \
  --header 'Content-Type: application/json' \
  --data '{
	"content": [{"type": "paragraph", "children": [{"text": "Hahaha"}]}]
}'
>>> {{"type"=>"paragraph", "children"=>[{"text"=>"Hahaha"}]}=>nil}

If I modify params to

requires :content, types: [Array, String, Hash]

Then with the same above request I get correct result:

[{"type"=>"paragraph", "children"=>[{"text"=>"Hahaha"}]}]

But when I request with String content:

curl --request POST \
  --url http://localhost:3000/api/testing \
  --header 'Content-Type: application/json' \
  --data '{
	"content": "abcd"
}'
>>> ["abcd"]

huyvohcmc avatar Jan 15 '21 06:01 huyvohcmc

Sounds like a bug. Turn it into a spec, maybe try fixing it?

dblock avatar Jan 15 '21 16:01 dblock

Hi 👋 I've just tested this potential bug with the last Grape version and it's working fine 👍

I'm always obtaining the expected response

[{"type"=>"paragraph", "children"=>[{"text"=>"Hahaha"}]}]

jcagarcia avatar Nov 28 '23 22:11 jcagarcia

@jcagarcia Thanks. Before we close we should be sure that 1) it was broken when the bug was reported (whichever version shipped last by Jan 14, 2021), 2) that we can bisect it to a specific fix/pull request, 3) that we have a spec for it.

dblock avatar Nov 28 '23 22:11 dblock