bastiW

bastiW

Hi,

I created an Ash application with the following:

  • AshGraphql
  • Subscription
  • AshSqlite

The issue is that the data does not show up in the graphiql interface. The issue can be reproduced with the reproduction repository.

Minimal Reproduction Repository

I followed the Video and the Guide here:

Showing Posts 1 to 5

bastiW

bastiW OP

Found workaround - OpenAI codex found it…

Switch from simple GraphQL interface to playground - as the simple seem to not support the subscriptions:
https://github.com/bastiW/my_subscription_app_sqlite/commit/5542ffc7770475b4443a60792ba886fbeb2a7b86

I also provided here a quick guide on how to setup it from scratch

bastiW

bastiW OP

I am still struggle with the Websocket subscription. I can not subscribe from external app like another react app - or my actual goal - from SwiftUI.

I have noticed that:

Works:
Interface :playground

Subscription

subscription PostCreated {
  postChanged {
    created {
      id
    	text
      text
    }
  }
}

Output in playground

{
  "data": {
    "postChanged": {
      "created": {
        "id": "01977fab-96d7-7d8a-bd31-c2a6cb4dc42d",
        "text": "Create Post"
      }
    }
  }
}

Output in browser console

[
    null,
    null,
    "__absinthe__:doc:",
    "subscription:data",
    {
        "result": {
            "data": {
                "postChanged": {
                    "created": {
                        "id": "01977fad-b7ea-7210-bea9-0c102811a77a",
                        "text": "Create Post"
                    }
                }
            }
        },
        "subscriptionId": "__absinthe__:doc:NDBuu9SaWIecvz5i9JO1q8t8pVxZNpzmkO5ZKzdfHxw=:A604DB20983D4EF98C369B525464A8023C4EB34291F6CDAC41CB20E481D3B2B6"
    }
]

From Postman
But when I try to connect from external tool like Postman (when connecting via the ws view on postman. I see error

Operation failed
23:01:48
Server sent no subprotocol
An error occurred with the WebSocket connection
23:01:48
Server sent no subprotocol
Handshake Details
Request Method: "GET"
Status Code: "101 Switching Protocols"
Request Headers
Sec-WebSocket-Version: "13"
Sec-WebSocket-Key: "HdTl8OncyDOMSGpq3lqhaQ=="
Connection: "Upgrade"
Upgrade: "websocket"
accept: "application/json"
content-type: "application/json"
Sec-WebSocket-Protocol: "graphql-ws"
user-agent: "PostmanClient/undefined (AppId=25983cc5-b338-491e-8e8b-799bb7bf37ae)"
Sec-WebSocket-Extensions: "permessage-deflate; client_max_window_bits"
Host: "localhost:4000"
Response Headers
date: "Tue, 17 Jun 2025 21:01:48 GMT"
upgrade: "websocket"
connection: "Upgrade"
sec-websocket-accept: "QERN/lfOJFzhnfB7E401vJgszSo="
cache-control: "max-age=0, private, must-revalidate"

When using the graphql view

Unexpected server response: 400
Handshake Details
Request Method: "GET"
Status Code: "400 Bad Request"
Request Headers
Sec-WebSocket-Version: "13"
Sec-WebSocket-Key: "wMy8ywB98auf9cR3WiMa1A=="
Connection: "Upgrade"
Upgrade: "websocket"
accept: "application/json"
content-type: "application/json"
Sec-WebSocket-Protocol: "graphql-ws"
user-agent: "PostmanClient/undefined (AppId=25983cc5-b338-491e-8e8b-799bb7bf37ae)"
Sec-WebSocket-Extensions: "permessage-deflate; client_max_window_bits"
Host: "localhost:4000"
Response Headers
date: "Tue, 17 Jun 2025 21:17:40 GMT"
content-length: "53"
vary: "accept-encoding"
cache-control: "max-age=0, private, must-revalidate"
x-request-id: "GEnxIqX_eofhF4sAAABD"
content-type: "application/json; charset=utf-8"

ken-kost

ken-kost

What’s the exact request? Maybe you’re missing ?vsn=2.0.0 which would specify Phoenix’s Channel Protocol. :thinking:

Check out this. :eyes: Maybe it could help.

Also you could try Altair GraphQL Client instead of Postman, could be easier in setup.

bastiW

bastiW OP

Thanks for your answer. To summarize:

My goal is to connect from a Swift App to my Elixir Ash Backend. I am using a playground to debug. I now tried it with Altair - it gives a lot of GraqhQL options.

(i did not check out Absinthe.Client - as this is not my use case)

Result of my debugging:

:playground: Works
Altair: Does not work

The difference in the log output is that with playground it logs the subscription. With Altair there is no such log (I marked it with THIS IS NOT LOGGED ON ALTAIR).

Debug Process

Branch: [Debug]
(GitHub - bastiW/my_subscription_app_sqlite at debug · GitHub)
Start Server with mix phx.server

I added to my graphql_socket.ex


  def connect(params, socket, connect_info) do
    path = case connect_info[:uri] do
      %URI{path: p} -> p
      _ -> "unknown"
    end
    
    IO.puts("GraphqlSocket params #{inspect(params)}")
    IO.puts("GraphqlSocket socket #{inspect(socket)}")
    IO.puts("GraphqlSocket connected path: #{path}")

    {:ok, socket}
  end

Modification in endpoint.ex

  socket "/ws/gql", MySubscriptionAppSqliteWeb.GraphqlSocket, websocket: [connect_info: [:uri]], longpoll: false

:Playground

Log output on server with web playground
https://i.postimg.cc/6y5bwNgj/playground.png

GraphqlSocket params %{"vsn" => "2.0.0"}
GraphqlSocket socket %Phoenix.Socket{assigns: %{}, channel: nil, channel_pid: nil, endpoint: MySubscriptionAppSqliteWeb.Endpoint, handler: MySubscriptionAppSqliteWeb.GraphqlSocket, id: nil, joined: false, join_ref: nil, private: %{}, pubsub_server: MySubscriptionAppSqlite.PubSub, ref: nil, serializer: Phoenix.Socket.V2.JSONSerializer, topic: nil, transport: :websocket, transport_pid: nil}
GraphqlSocket connected path: /ws/gql/websocket
[info] CONNECTED TO MySubscriptionAppSqliteWeb.GraphqlSocket in 5ms
  Transport: :websocket
  Serializer: Phoenix.Socket.V2.JSONSerializer
  Parameters: %{"vsn" => "2.0.0"}
[info] JOINED __absinthe__:control in 58µs
  Parameters: %{}
[debug] ABSINTHE schema=MySubscriptionAppSqliteWeb.GraphqlSchema variables=%{}
---

// ---> THIS IS NOT LOGGED ON ALTAIR:

subscription PostCreated {
  postChanged {
    created {
      id
        text
      text
    }
  }
}
---
[debug] -- Absinthe Phoenix Reply --
{:ok, %{subscriptionId: "__absinthe__:doc:NDBuu9SaWIecvz5i9JO1q8t8pVxZNpzmkO5ZKzdfHxw=:A604DB20983D4EF98C369B525464A8023C4EB34291F6CDAC41CB20E481D3B2B6"}}
----------------------------

Altair

https://i.postimg.cc/s1JHt26G/altair-subscription-1.png
https://i.postimg.cc/V5wHGtRc/altair-subscription-2.png

On Altair there is no log of the subscription on the server.

GraphqlSocket params %{"vsn" => "2.0.0"}
GraphqlSocket socket %Phoenix.Socket{assigns: %{}, channel: nil, channel_pid: nil, endpoint: MySubscriptionAppSqliteWeb.Endpoint, handler: MySubscriptionAppSqliteWeb.GraphqlSocket, id: nil, joined: false, join_ref: nil, private: %{}, pubsub_server: MySubscriptionAppSqlite.PubSub, ref: nil, serializer: Phoenix.Socket.V2.JSONSerializer, topic: nil, transport: :websocket, transport_pid: nil}
GraphqlSocket connected path: /ws/gql/websocket
[info] CONNECTED TO MySubscriptionAppSqliteWeb.GraphqlSocket in 1ms
  Transport: :websocket
  Serializer: Phoenix.Socket.V2.JSONSerializer
  Parameters: %{"vsn" => "2.0.0"}

// ---> Here no log anymore. It just reconnects again and agian

bastiW

bastiW OP

The subscription is a Phoenix Subscription. So it is not a normal Websocket GraphQL subscription which is compatible with Apollo or Relay GraphQL.

When I add some roundtrips around on the setup it works - still looks like that sometimes the connection breaks.

JS Workaround with Roundtrip

How can I change the Ash Absinthe code, so that it is a standard Apollo or Relay Subscription?

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews