CargoSense / absinthe_client

A GraphQL client designed for Elixir Absinthe.
https://hexdocs.pm/absinthe_client
MIT License
74 stars 7 forks source link

Invalid headers format using WebSocket #19

Open Neylix opened 4 months ago

Neylix commented 4 months ago

Hello there ! Firstly I would thanks you for this library.

While the querying part over HTTP works well, I encountered an issue using WebSocket. When I try to connect an absinthe web socket I get an error from Req even before sending the request. The code triggering the error:

Req.new()
|> AbsintheClient.attach(graphql: "query { #{format_graphql(body)} }")
|> Req.merge(method: :post, url: "/api")
|> Req.request()

The interesting part of the error is :

  {:error,
   %NimbleOptions.ValidationError{
     message:
       ~s(invalid value for :headers option: expected list, got: %{"accept-encoding" => ["gzip"], "user-agent" => ["req/0.5.4"]}),
     key: :headers,
     value: %{"accept-encoding" => ["gzip"], "user-agent" => ["req/0.5.4"]},
     keys_path: []
   }}

The error happens on https://github.com/CargoSense/absinthe_client/blob/c178e4d2daa74e00d9773997d4e7e9bc47d1f02e/lib/absinthe_client/web_socket.ex#L173

From the documentation of SlipStream on version 1.1.1 "Headers must be provided as two-tuples where both elements are binaries" while the Req headers format is a map.

I locally fixed the issue replacing req.headers by

Enum.map(req.headers, fn {key, value} -> {key, Jason.encode!(value)} end)

But I'm not sure using Jason to encode values as string is the best option.

dvjoness commented 2 months ago

Hi there You can update req up to 0.5.6 version and use config to avoid the error

config :req, :legacy_headers_as_lists, true
Neylix commented 4 days ago

Hello ! Thank's for the tips, I didn't know this config option.

But using this option breaks the rest of my application since req is used for other request than absinthe client and I would need to update all headers everywhere to use list instead of map. Also the project I'm developing is a library and I cannot enforce other project requiring my library to use req headers as list.

Also, req introduced headers as map in version 4.0.0, and as absinthe_client require {:req, "~> 0.4"} I expect it to work with the map headers. So for me absinthe_client should handle this rather than forcing a legacy config.

Thank's for the update