GraphiQL - Cowboy 431 exception for absinthe mutation that accepts a list of params and returns a list of objects

I realize this might be a stupid question, but I can’t see where my mistake is.
I want to create a GraphQL mutation with absinthe that receives a list of parameteres, creates an object from each of the elements of the list, and then returns a list with the data for the created objects.

In my schema, I have something similar to:

field :create_cars, list_of(:car) do
      arg :params, list_of(:car_params)

      resolve &Resolvers.Cars.create/3
end

Where :car is previously defined as an object, such as:

object :car do
    field :colour, :string
    field :origin, :string
    field :id, :integer
   ...
end

And :car_params is defined as an input_object:

input_object :car_params do
    field :colour, :string
    field :origin, :string
    ...
end

In the Cars resolver, I have so far a function def create(_root, %{params: params}, _info) do ... where for the moment I just want to print the params for debugging. I know that the resolver should return {:ok, any()} so I added a sample response so that it won’t raise an exception. The problem is the mutation doesn’t reach the resolver at all and I think it there is something wrong with my definitions somewhere. My testing in GraphiQL just returns an empty string "", but I think that is because Cowboy returns 431 maybe because GraphQL returns an error that is too large (might be wrong here as well).

Am I trying to do something that is not idiomatic? I don’t think this should be a really strange case, though.

Edit:

I forgot to mention the mutation I’m testing with looks like this:

mutation { createCars(params: [
  { colour: "red", origin: "Japan" },
  { colour: "blue", origin: "Germany"}
]) { id } }

I know that I can serialize the parameters to JSON and send them as one string, but I’d be happy if I can avoid that for the sake of clarity.

I just tested from iex by passing the mutation to Absinthe.run(MyAppWeb.Schema) in iex and it works properly but for some reason it doesn’t work through GraphiQL.

My recollection is that if you have many independent updates or creations to perform at once, the most idiomatic approach is to duplicate the mutation block within your GQL document rather than provide mutations that operate on one subject item and other mutations that operate on a collection. That would not scale super effectively to a single call trying to create 100+ items, though, and if only one or a few arguments vary from item to item it would be quite repetitive.

Creating a set of things this way is fine, but without a more complete example or some backend logs it’s hard to offer more specific help.

I know that the resolver should return {:ok, any()} so I added a sample response so that it won’t raise an exception

What sample response are you providing?

For the moment I’m returning the list of all existing Cars and when I test it from iex the mutation returns the id of all Cars properly and the params are received.

I tested by doing:

"""
mutation { createCars(params: [
  { colour: "red", origin: "Japan" },
  { colour: "blue", origin: "Germany"}
]) { id } }
""" 
|> Absinthe.run(MyAppWeb.Schema) 

And received the response:

{:ok,
 %{
   data: %{
     "createCars" => [
       %{"id" => "2"}
     ]
   }
 }

These are sample examples, but I’m basically doing the same with a different name of the mutation, parameters and different strings for their values.

OK cool, can you perhaps screen cap what you’re running in GraphiQL?

What do you mean by duplicating the mutation block within the GraphQL document?

Also, for my purposes the mutation would create or update not more than 10 records. I can use the normal mutation I already have that creates one record and call it a few times in a loop with different parameters, but I wanted to try to improve it.

I’ll try. I changed some of the names again, but this is what I do.

The mutation in GraphiQL (target and type are defined as fields for the input object and identifier for the object that is returned):

The servers raises a Cowboy exception:

When I try it from the terminal it works (with some of my debugging messages):

This is the currently only existing record, and as I am returning a list of the existing records without creating new ones, is is the sole element in the list.

I’m wondering could it be perhaps due to the fact that I test on localhost and have some cookies from other applications as well that end up being too much?

Well, I cleaned up some of my localhost cookies and the problem was solved. I’m sorry for taking your time, I should have literally responded to the Cowboy 431 exception from the beginning. After all, my iex tests showed no problem with Absinthe or the schema.

1 Like

I updated the title of the post to be more explicit that this was related to Cowboy.

1 Like