Skip to content

feat: Add Server-Sent Events transport for incremental delivery#306

Open
jwaldrip wants to merge 10 commits intoabsinthe-graphql:mainfrom
gigsmart:gigmart/defer-stream-incremental
Open

feat: Add Server-Sent Events transport for incremental delivery#306
jwaldrip wants to merge 10 commits intoabsinthe-graphql:mainfrom
gigsmart:gigmart/defer-stream-incremental

Conversation

@jwaldrip
Copy link
Copy Markdown

@jwaldrip jwaldrip commented Sep 5, 2025

Summary

This PR adds Server-Sent Events (SSE) transport support to absinthe_plug for incremental delivery with @defer and @stream directives.

⚠️ DEPENDENCY NOTICE

This PR depends on gigsmart/absinthe#gigmart/defer-stream-incremental
The main absinthe package must be merged first before this PR can be merged.

Features

  • Server-Sent Events (SSE) adapter for HTTP streaming
  • Multipart response format support
  • Proper chunked transfer encoding
  • Graceful connection handling

Implementation

  • Absinthe.Plug.Incremental.SSE - SSE transport adapter
  • Event stream formatting
  • Connection lifecycle management

Testing

  • SSE protocol compliance
  • Chunked encoding validation
  • Connection recovery scenarios

Breaking Changes

None - incremental delivery is opt-in and backward compatible.

jwaldrip and others added 9 commits September 5, 2025 12:12
Implements SSE transport for @defer and @stream directives:
- Server-Sent Events (SSE) adapter for HTTP streaming
- Multipart response format support
- Proper chunked transfer encoding

DEPENDS ON: absinthe package defer-stream-incremental branch must be merged first

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
BREAKING: Refactored single-file SSE implementation into modular structure:
- SSE.EventFormatter: Event formatting utilities
- SSE.ConnectionManager: Connection lifecycle management
- SSE.QueryProcessor: GraphQL query processing
- SSE.Router: Phoenix router helpers and plugs

docs: Add comprehensive HTTP/SSE incremental delivery documentation

- Server-Sent Events implementation guide
- Client-side integration examples (vanilla JS, React)
- Performance optimization and monitoring
- Security considerations and troubleshooting

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
…y testing

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
…very

Point to gigsmart/absinthe branch gigmart/defer-stream-incremental
for testing the @defer and @stream directive implementation.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Update installation dependencies in README_INCREMENTAL.md to point to the
remote git repositories instead of hex packages for testing incremental
delivery features.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Move incremental delivery content from temporary README_INCREMENTAL.md
into the main README.md file. Remove temporary file and properly document
the HTTP/SSE incremental delivery features.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@jwaldrip
Copy link
Copy Markdown
Author

jwaldrip commented Feb 6, 2026

Checking in on the SSE transport for incremental delivery. This is a companion to absinthe#1377. Any thoughts or concerns?

Copy link
Copy Markdown

@bryanjos bryanjos left a comment

Choose a reason for hiding this comment

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

This looks good so far. If possible, it would be nice to have some tests for it. And like you mentioned it will have to wait until the absinthe changes merge in. Then you can update the dependency references

@binaryseed
Copy link
Copy Markdown
Contributor

FYI There is support for SSE for subscriptions here already: https://github.com/absinthe-graphql/absinthe_plug/blob/main/lib/absinthe/plug.ex#L366-L401

Might be worth reviewing that for overlap, maybe SSE support could be unified

- Refactor existing subscription SSE to use shared ConnectionManager for
  header setup, unifying SSE support between subscriptions and incremental
  delivery (addresses overlap noted by @binaryseed)
- Standardize keep-alive comment format (: keep-alive) across both paths
- Add comprehensive tests for EventFormatter (event formatting, error
  response wrapping) and ConnectionManager (accept detection, header
  setup, keep-alive scheduling)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jwaldrip
Copy link
Copy Markdown
Author

jwaldrip commented Mar 4, 2026

@binaryseed Good call — there was definitely overlap between the existing subscription SSE in Absinthe.Plug.subscribe/3 and the new incremental delivery SSE. I've refactored to unify them:

  • The existing subscribe/3 now uses the shared ConnectionManager.setup_sse_headers/1 for connection setup, so both subscription SSE and incremental delivery SSE go through the same header configuration (content-type, cache-control, connection keep-alive, nginx buffering, CORS)
  • Standardized the keep-alive comment format across both paths

The two remain separate at the event loop level since they handle fundamentally different message patterns (subscription broadcasts vs incremental delivery payloads), but the connection infrastructure is now shared.

@bryanjos Added tests for EventFormatter (event formatting, error response wrapping) and ConnectionManager (accept detection, header setup, keep-alive scheduling). Full test suite passes (105 tests, 0 failures). Will update the dependency reference to point at the mainline absinthe once the incremental delivery changes land upstream.

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