Subscription

Listen for real-time updates from your server using GraphQL Subscriptions.

SubscriptionExample.svelte
<script lang="ts">
  import { graphql } from '$houdini'

  // this information should usually come from a fragment
  export let itemID: string

  // will start listening onMount (browser only)
  const updates = graphql(`
    subscription ItemUpdate($id: ID!) {
      itemUpdate(id: $id) {
        item {
          id
          completed
          text
        }
      }
    }
  `)


  $: updates.listen({ id: itemID })
</script>

latest value: {$updates.data.itemUpdate.item.text}
SubscriptionExample.svelte
<script>
    import { graphql } from '$houdini'
    
    // this information should usually come from a fragment
    /* @type { string } */
    export let itemID
    
    // will start listening onMount (browser only)
    const updates = graphql(`
        subscription ItemUpdate($id: ID!) {
            itemUpdate(id: $id) {
                item {
                    id
                    completed
                    text
                }
            }
        }
    `)
    
    $: updates.listen({ id: itemID })
</script>

latest value: {$updates.data.itemUpdate.item.text}

Subscriptions can be defined like any other document and are triggered using the subscription store’s listen method:

List Operations

Subscription bodies can contain all of the list operations described in this document.

Configuring the client

Houdini can work with any websocket client as long as you can provide an a function that returns an object that satisfies the SubscriptionHandler interface to the subscriptions plugin you can import from $houdini/plugins.

Using graphql-ws

If your API supports the graphql-ws protocol, you can create a client and pass it directly:

src/client.ts
import { createClient } from 'graphql-ws'
import { subscription } from '$houdini/plugins'
export default new HoudiniClient({
  url: "...",
  plugins: [
    subscription(() => createClient({
      url: 'ws://api.url'
    }))
  ]
})
src/client.js
import { createClient } from 'graphql-ws'
import { subscription } from '$houdini/plugins'
export default new HoudiniClient({
  url: "...",
  plugins: [
    subscription(() => createClient({
      url: 'ws://api.url'
    }))
  ]
})

Using subscriptions-transport-ws

If you are using the deprecated subscriptions-transport-ws library and associated protocol, you will have to slightly modify the above block:

src/client.ts
import { SubscriptionClient } from 'subscriptions-transport-ws'
import { browser } from '$app/environment'
import { subscription } from '$houdini/plugins'
function createClient() {
  // instantiate the transport client
  const client = new SubscriptionClient('ws://api.url', {
    reconnect: true,
  })

  // wrap the client in something houdini can use
  return {
    subscribe(payload, handlers) {
      // send the request
      const { unsubscribe } = client.request(payload).subscribe(handlers)

      // return the function to unsubscribe
      return unsubscribe
    },
  }
}

export default new HoudiniClient({
  url: "...",
  plugins: [
    subscription(createClient)
  ]
})
src/client.js
import { SubscriptionClient } from 'subscriptions-transport-ws'
import { browser } from '$app/environment'
import { subscription } from '$houdini/plugins'
function createClient() {
  // instantiate the transport client
  const client = new SubscriptionClient('ws://api.url', {
    reconnect: true,
  })

  // wrap the client in something houdini can use
  return {
    subscribe(payload, handlers) {
      // send the request
      const { unsubscribe } = client.request(payload).subscribe(handlers)

      // return the function to unsubscribe
      return unsubscribe
    },
  }
}

export default new HoudiniClient({
    url: '...',
    plugins: [subscription(createClient)],
})

Server-Sent Events

If your server supports the latest Server-sent events, you can use them to power your subscriptions:

src/client.ts
import { createClient } from 'graphql-sse'
import { subscription } from '$houdini/plugins'

export default new HoudiniClient({
  url: "...",
  plugins: [
    subscription(() => createClient({url: '...'}))
  ]
})
src/client.js
import { createClient } from 'graphql-sse'
import { subscription } from '$houdini/plugins'

export default new HoudiniClient({
    url: '...',
    plugins: [subscription(() => createClient({ url: '...' }))],
})

Authentication

Subscriptions integrate with the rest of the session logic provided by houdini. When your session value, fetchParams or metadata changes a new subscription client will be created based on that new information. You can use this information to pass connection parameters to your subscription client. For example, authenticating graphql-ws would look something like:

src/client.ts
import { createClient } from 'graphql-ws'
import { subscription } from '$houdini/plugins'
export default new HoudiniClient({
  url: "...",
  plugins: [
    subscription(({ session }) => createClient({
      url: 'ws://api.url',
      connectionParams: () => {
        return {
          headers: {
            Authorization: `Bearer ${session.token}`,
          },
        }
      },
    }))
  ]
})
src/client.js
import { createClient } from 'graphql-ws'
import { subscription } from '$houdini/plugins'
export default new HoudiniClient({
  url: "...",
  plugins: [
    subscription(({ session }) => createClient({
      url: 'ws://api.url',
      connectionParams: () => {
        return {
          headers: {
            Authorization: `Bearer ${session.token}`,
          },
        }
      },
    }))
  ]
})