graphql

package module
v0.3.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 5, 2021 License: MIT Imports: 11 Imported by: 5

README

pkg.go.dev

About

go-graphql-ws is a Go client implementation of the GraphQL over WebSocket Protocol. This is not a standard GraphQL client; the GraphQL endpoint must support the WebSocket Protocol. This package has been written specifically with Hasura GraphQL Engine in mind, but any server implementing the WebSocket Protocol should work.

Package Status

This package is still under testing; use it with caution. A v1 version has not been released yet so the API should not be considered stable.

Installing

go get github.com/korylprince/go-graphql-ws

Usage

See Examples.

Issues

If you have any issues or questions create an issue.

Documentation

Overview

Package graphql implements a client for the GraphQL over WebSocket Protocol described at https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md.

Index

Examples

Constants

View Source
const (
	MessageTypeConnectionInit      = "connection_init"
	MessageTypeConnectionAck       = "connection_ack"
	MessageTypeConnectionError     = "connection_error"
	MessageTypeConnectionTerminate = "connection_terminate"
	MessageTypeConnectionKeepAlive = "ka"
	MessageTypeStart               = "start"
	MessageTypeData                = "data"
	MessageTypeComplete            = "complete"
	MessageTypeStop                = "stop"
	MessageTypeError               = "error"
)

Variables

DefaultDialer is a wrapper for websocket.DeafultDialer

View Source
var GenerateSubscriptionID func() string = func() string {
	return uuid.Must(uuid.NewV4()).String()
}

GenerateSubscriptionID is a function that returns unique IDs used to track subscriptions. By default UUIDv4's are used

Functions

func ParseError

func ParseError(payload []byte) error

ParseError parses and returns an error for the various different formats a GraphQL server might return an error

Types

type Conn

type Conn struct {
	// contains filtered or unexported fields
}

Conn is a connection to a GraphQL WebSocket endpoint

func (*Conn) Close

func (c *Conn) Close() error

Close closes the Conn or returns an error if one occurred

func (*Conn) Execute

func (c *Conn) Execute(ctx context.Context, payload *MessagePayloadStart) (data *MessagePayloadData, err error)

Execute executes the given payload and returns the result or an error if one occurred The given context can be used to cancel the request

Example
var query = &graphql.MessagePayloadStart{
	Query: `
		query get_users {
		  user {
			id
			name
		  }
		}
`,
}

headers := make(http.Header)
headers.Add("X-Hasura-Admin-Secret", "test")

conn, _, err := graphql.DefaultDialer.Dial("ws://localhost:8080/v1/graphql", headers, nil)
if err != nil {
	log.Fatalln("Unable to connect:", err)
}

payload, err := conn.Execute(context.Background(), query)
if err != nil {
	log.Fatalln("Unable to Execute:", err)
}
if len(payload.Errors) > 0 {
	log.Fatalln("Unable to Execute:", payload.Errors)
}
log.Println("Payload Received:", string(payload.Data))
Output:

Example (Cancel)
var query = &graphql.MessagePayloadStart{
	Query: `
		query get_users {
		  user {
			id
			name
		  }
		}
`,
}

headers := make(http.Header)
headers.Add("X-Hasura-Admin-Secret", "test")

conn, _, err := graphql.DefaultDialer.Dial("ws://localhost:8080/v1/graphql", headers, nil)
if err != nil {
	log.Fatalln("Unable to connect:", err)
}

ctx, cancel := context.WithCancel(context.Background())
//cancel long running query
go func() {
	cancel()
}()

_, err = conn.Execute(ctx, query)
log.Println("Canceled:", errors.Is(ctx.Err(), err))
Output:

func (*Conn) SetCloseHandler added in v0.3.0

func (c *Conn) SetCloseHandler(f func(code int, text string))

SetCloseHandler sets the handler for when the Conn is closed, expectedly or not. The code argument to h is the received close code or CloseNoStatusReceived if the close message is empty

func (*Conn) Subscribe

func (c *Conn) Subscribe(payload *MessagePayloadStart, f func(message *Message)) (id string, err error)

Subscribe creates a GraphQL subscription with the given payload and returns its ID, or returns an error if one occurred. Subscription Messages are passed to the given function handler as they are received

Example
var subscription = &graphql.MessagePayloadStart{
	Query: `
		subscription get_users {
		  user {
			id
			name
		  }
		}
`,
}

headers := make(http.Header)
headers.Add("X-Hasura-Admin-Secret", "test")

conn, _, err := graphql.DefaultDialer.Dial("ws://localhost:8080/v1/graphql", headers, nil)
if err != nil {
	log.Fatalln("Unable to connect:", err)
}

id, err := conn.Subscribe(subscription, func(m *graphql.Message) {
	if m.Type == graphql.MessageTypeError {
		err := graphql.ParseError(m.Payload)
		//handle err
		_ = err
		return
	} else if m.Type == graphql.MessageTypeComplete {
		//clean up
		return
	}
	payload := new(graphql.MessagePayloadData)
	if err := json.Unmarshal(m.Payload, payload); err != nil {
		//handle error
		return
	}
	if len(payload.Errors) > 0 {
		//handle error
		return
	}
	log.Println("Payload Received:", string(payload.Data))
})
if err != nil {
	log.Fatalln("Unable to Subscribe:", err)
}

//do other stuff
time.Sleep(time.Second * 5)

if err = conn.Unsubscribe(id); err != nil {
	log.Fatalln("Unable to Unsubscribe:", err)
}
Output:

func (*Conn) Unsubscribe

func (c *Conn) Unsubscribe(id string) error

Unsubscribe stops the subscription with the given ID or returns an error if one occurred

type Dialer

type Dialer struct {
	*websocket.Dialer
	Debug bool
}

Dialer is a wrapper for websocket.Dialer

func (*Dialer) Dial

func (d *Dialer) Dial(urlStr string, requestHeader http.Header, connectionParams *MessagePayloadConnectionInit) (*Conn, *http.Response, error)

Dial creates a new Conn by calling DialContext with a background context

func (*Dialer) DialContext

func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader http.Header, connectionParams *MessagePayloadConnectionInit) (*Conn, *http.Response, error)

DialContext creates a new Conn with the same parameters as websocket.DialContext. connectionParams is passed to the GraphQL server and is described further at https://www.apollographql.com/docs/react/data/subscriptions/#authentication-over-websocket

type Error

type Error struct {
	Message    string                 `json:"message"`
	Locations  []Location             `json:"locations"`
	Path       []interface{}          `json:"path"`
	Extensions map[string]interface{} `json:"extensions,omitempty"`
}

Error is a GraphQL Error

func (*Error) Error

func (e *Error) Error() string

Error implements the error interface

type Errors

type Errors []Error

func (Errors) Error

func (e Errors) Error() string

Error implements the error interface

type Location

type Location struct {
	Line   int `json:"line"`
	Column int `json:"column"`
}

Location is a location in a GraphQL document

type Message

type Message struct {
	Type    string          `json:"type"`
	ID      string          `json:"id,omitempty"`
	Payload json.RawMessage `json:"payload,omitempty"`
}

Message is a GraphQL message. A Message's Payload can be JSON decoded into one of the MessagePayload* types if present

func (*Message) SetPayload

func (m *Message) SetPayload(payload interface{}) error

SetPayload sets Message.Payload to the given payload or returns an error if one occurred

type MessagePayloadConnectionInit

type MessagePayloadConnectionInit map[string]interface{}

type MessagePayloadData

type MessagePayloadData struct {
	Data   json.RawMessage `json:"data"`
	Errors Errors          `json:"errors,omitempty"`
}

type MessagePayloadStart

type MessagePayloadStart struct {
	Query         string                 `json:"query"`
	Variables     map[string]interface{} `json:"variables,omitempty"`
	OperationName string                 `json:"operationName,omitempty"`
}

type UnknownError

type UnknownError struct {
	Original []byte
}

func (*UnknownError) Error

func (e *UnknownError) Error() string

Error implements the error interface

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL