Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change SSE response structure so that it's compatible with GraphQL SSE standard #292

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

perzanko
Copy link

@perzanko perzanko commented Jul 29, 2024

Description
The current payload of a subscription response in the SSE protocol looks like this.

{"data": {."foo": "bar" } }\n\n

It is simply encoded JSON with a new line.

The proposed response format is as follows:

event: next\ndata: {"data": {."foo": "bar" } }\n\n

The encoded response additionally contains an event segment event: next and the data is prefixed with a data: field, indicating data segment. This structure is consistent with GraphQL over Server-Sent Events Protocol specification and official SSE standard.

Reason
Many graphql clients expect a response consistent with the above standard. An example of this is graphql-mesh, which expects responses from subgraph services sent in a structured manner. Or even the highly popular client graphql-sse used in browsers also requires this format.

⚠️ Please note
This is a breaking change and should be implemented with backward compatibility. Perhaps introducing an additional configuration option or an option to override the response format would be appropriate in this case, perhaps even more appropriate.

@perzanko perzanko marked this pull request as ready for review July 29, 2024 20:48
@perzanko
Copy link
Author

@benwilson512 😉☝️

Copy link
Contributor

@benwilson512 benwilson512 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @perzanko thanks for the PR!

As you note, this is a backwards incompatible change. I think we should support some sort of flag on probably the Absinthe.Plug plug that we can use to switch between the types of return shapes.

@fladens
Copy link

fladens commented Dec 10, 2024

@perzanko are you planning on fixing this still, or should I take over to add this flag?
It doesn't really work for me else for my current setup.

Here for anyone who comes across this and needs a bit ugly but working workaround.
(I am also using a custom AbsinthePubsub for SSE)

plug Absinthe.Plug,
  schema: ExampleApiWeb.Graphql.AdminSchema,
  pubsub: ExampleApiWeb.Graphql.AbsinthePubsub,
  json_codec: __MODULE__

@doc false
def encode!(%{sub: data}, config) do
  "event: next\ndata: #{Jason.encode!(data, config)}"
end

@doc false
def encode!(value, config) do
  Jason.encode!(value, config)
end

and

def publish_subscription(topic, result) do
  broadcast = %{
    topic: topic,
    event: "subscription:data",
    payload: %{
      result: %{sub: result},
      subscriptionId: topic
    }
  }

  Phoenix.PubSub.local_broadcast(@pubsub, topic, broadcast)
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants