Upload ,ecto ,elixir graphql

I have created my schema , my table expenses and all it contains an attribut document with type string , I want to use as a :upload and test it via graphiql
I did that in my mutation to create expense : .

arg(:file_upload, non_null(:upload))
resolve(fn args, _ ->
  # this is a `%Plug.Upload{}` struct. A server (a GenServer specifically) that manages uploaded files.
  args.file_upload
  {:ok, "success"}
end)

I did a test in graphiql but it returns argument fileUpload an invalide Value

GraphiQL does not support file uploads at this time.

do you have a suggestion please?

even my curl Command curl -X POST -F query=“mutation { CreateExpense(file_upload “Elixir_in_Action”)}” -F Elixir_in_Action=@Elixir_in_Action.pdf localhost:80/graphql
returns curl -X POST -F query=“mutation { createExpense(file_upload: “Elixir_in_Action”)}” -F Elixir_in_Action=@Elixir_in_Action.pdf localhost:80/graphql
Warning: setting file Elixir_in_Action.pdf failed!

404 Not Found

404 Not Found


nginx/1.16.0

If you’re getting a 404 this means that the route is not found. Do you have a /graphql route defined in your router?

Are you sure you configured your nginx correctly? I find it quite uncommon that it shows its 404 instead of phoenix’…

Here is a quick (& dirty) implementation :

In schema

  object :governance_mutations do
    @desc "Upload a file"
    field :upload_file, :string do
      arg :file_data, non_null(:upload)
      resolve(&Resolvers.GovernanceResolver.upload_file/2)
    end

In resolver :

  def upload_file(%{file_data: %Plug.Upload{content_type: _content, filename: orig_filename, path: path_to_filename} = _args}, _) do
    Governances.upload_on_request_type(orig_filename, path_to_filename)
    {:ok, "success"}
  end

Then :

  def upload_on_request_type(orig_filename, path_to_filename) do
    case File.read(path_to_filename) do
        {:ok, contents} ->
                Logger.info("Reading file succeeded")
                %RequestType{}
                |> RequestType.changeset(%{name: "Photo", business_line_id: "1", file_data: contents})
                |> Repo.insert()

                {:ok, "Success"}

        {:error, reason} ->
                Logger.info("File reading error : #{inspect(reason)}")
                {:error, reason}
    end
  end

We need to tell Postgres to accept binary stuff before (otherwise simply copy paste the file elsewhere is filesystemstorage is ok, or even sending it to any bucket).

Thank you @benwilson512 by the way for this really really awesome work :smiley:

2 Likes